grep是UNIX中的一个制表符

如何在Unix平台上的文件中grep选项卡(\t) ?

331112 次浏览

如果使用GNU grep,你可以使用perl风格的regexp:

grep -P '\t' *

一种方法是(这是Bash)

grep -P '\t'

-P打开Perl正则表达式,因此\t将工作。

正如用户放松所说,它可能是特定于GNU grep的。另一种方法是在shell、编辑器或终端允许的情况下插入一个制表符。

使用gawk,将字段分隔符设置为TAB (\t)并检查字段的数量。如果多于1,则有/有制表符

awk -F"\t" 'NF>1' file
我从来没有设法使“\t”元字符与grep工作。 然而,我发现了两个替代方案:

  1. 使用<Ctrl-V> <TAB>(按Ctrl-V然后输入tab)
  2. 使用awk: foo | awk '/\t/'

诀窍是在引号前使用$符号。它也适用于减少和其他工具。

grep $'\t' sample.txt

答案更简单。编写grep并在引号中输入tab键,它至少在ksh中工作得很好

grep "  " *

一个好的选择是使用sed。

sed -n '/\t/p' file

示例(工作在bash, sh, ksh, csh,..):

[~]$ cat testfile
12 3
1 4 abc
xa      c
a       c\2
1 23

[~]$ sed -n '/\t/p' testfile
xa      c
a       c\2
[~]$ sed -n '/\ta\t/p' testfile
a       c\2

(以下答案已根据评论中的建议进行了编辑。谢谢大家)

我用ksh

grep "[^I]" testfile

使用echo为你插入标签grep "$(echo -e \\t)"

您可以输入

Grep \t foo

或者< / p >
grep '\t' foo

在文件foo中搜索制表符。您可能还可以使用其他转义代码,尽管我只测试了\n。虽然这相当耗时,而且不清楚为什么要这样做,但在zsh中,您还可以键入制表符,回到开头,grep并将制表符用引号括起来。

多次查找空格[[:空间:]]*

grep[[:空间 :]]*'.''.'

会发现这样的东西:

“账单”..

这些是单引号('),而不是双引号(")。这是在grep中进行连接的方法。= -)

这对于AIX很有效。我正在搜索包含JOINED<\t>ACTIVE的行

voradmin cluster status | grep  JOINED$'\t'ACTIVE


vorudb201   1       MEMBER(g) JOINED        ACTIVE
*vorucaf01   2       SECONDARY JOINED        ACTIVE

+1方式,工作在ksh,破折号等:使用printf插入制表符:

grep "$(printf 'BEGIN\tEND')" testfile.txt

使用'sed-as-grep'方法,但是用个人偏好的可见字符替换制表符是我最喜欢的方法,因为它清楚地显示了哪些文件包含所请求的信息,以及它在行的位置:

sed -n 's/\t/\*\*\*\*/g' file_name

如果您希望使用行/文件信息,或其他grep选项,但也希望看到制表符的可见替换,您可以通过

grep -[options] -P '\t' file_name | sed 's/\t/\*\*\*\*/g'

举个例子:

$ echo "A\tB\nfoo\tbar" > test
$ grep -inH -P '\t' test | sed 's/\t/\*\*\*\*/g'
test:1:A****B
test:2:foo****bar

编辑:显然,上面的内容只对查看文件内容以定位选项卡有用——如果目标是将选项卡作为更大的脚本会话的一部分来处理,那么这没有任何有用的用途。

Ask Ubuntu中的这个答案:

告诉grep使用由Perl定义的正则表达式(Perl有 \t as tab):

grep -P "\t" <file name>

使用文字制表符:

grep "^V<tab>" <filename>

使用printf为你打印制表符:

grep "$(printf '\t')" <filename>

你可能想要使用grep "$(echo -e '\t')"

唯一的要求是echo能够解释反斜杠转义。

这些可选的二进制识别方法是完全有效的。而且,我真的很喜欢使用awk的那个,因为我不太记得单个二进制字符的语法用法。然而,它也应该可以以POSIX可移植的方式为shell变量赋值(即TAB=echo "@" | tr "\100" "\011"),然后从那里以POSIX可移植的方式在任何地方使用它;以及(即grep "$TAB"文件名)。虽然这个解决方案适用于TAB,但它也适用于其他二进制字符,当在赋值中使用另一个所需的二进制值时(而不是制表符'tr'的值)。

grep "$(printf '\t')"在Mac OS X上为我工作

在其他答案中给出的$'\t'符号是特定于shell的——它似乎在bash和zsh中工作,但不是通用的。

注意:下面是针对fish shell的,在bash中不起作用:

fish shell中,可以使用不带引号的\t,例如:

grep \t foo.txt

或者可以使用十六进制或unicode符号,例如:

grep \X09 foo.txt
grep \U0009 foo.txt

(这些符号对于更深奥的字符很有用)

因为这些值必须是不加引号的,所以可以将加引号的值和不加引号的值进行拼接:

grep "foo"\t"bar"

基本上有两种解决方法:

  1. (推荐)使用grep(1)支持的正则表达式。现代grep(1)支持两种形式的POSIX 1003.2 regex语法:基本(过时)REs和现代 REs。语法在re_format(7)和regex(7)手册页中详细描述,它们分别是BSD和Linux系统的一部分。GNU grep(1)也支持由pcre(3)库提供的与perl兼容的REs。

    在正则表达式语言中,制表符通常由\t原子编码。原子由BSD扩展正则表达式(BSD兼容系统上的egrepgrep -E)以及perl兼容的REs (pcregrep, GNU grep -P)支持。

    基本正则表达式和Linux扩展REs显然都不支持\t。请参考UNIX实用程序手册页以了解它支持哪种正则表达式语言(因此有sed(1)、awk(1)和pcregrep(1)正则表达式之间的区别)。

    因此,在Linux上:

    $ grep -P '\t' FILE ...
    

    在类似BSD的系统上:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Pass the tab character into pattern. This is straightforward when you edit a script file:

    # no tabs for Python please!
    grep -q '   ' *.py && exit 1
    

    然而,当在交互式shell中工作时,您可能需要依赖shell和终端功能来在行中输入适当的符号。在大多数终端上,这可以通过Ctrl+V组合键来实现,该组合键指示终端逐字处理下一个输入字符(V代表“逐字”):

    $ grep '<Ctrl>+<V><TAB>' FILE ...
    

    一些shell可能提供对命令排版的高级支持。这样,在bash(1)中$'string'形式的单词被特殊对待:

    bash$ grep $'\t' FILE ...
    

    请注意,虽然在命令行中很好,但当脚本移动到另一个平台时,可能会产生兼容性问题。另外,在使用特价时要小心引号,详情请咨询bash(1)。

    对于Bourne shell(不仅如此),可以使用printf(1)增强的命令替换来模拟相同的行为,以构造适当的regex:

    $ grep "`printf '\t'`" FILE ...
    

在表达式中插入制表符的另一种方法是使用Bash中不太为人所知的$'\t'引号:

grep $'foo\tbar'        # matches eg. 'foo<tab>bar'

(注意,如果你匹配的是固定字符串,你可以使用-F模式。)

有时使用变量可以使符号更易于阅读和管理:

tab=$'\t'               # `tab=$(printf '\t')` in POSIX
id='[[:digit:]]\+'
name='[[:alpha:]_][[:alnum:]_-]*'
grep "$name$tab$id"     # matches eg. `bob2<tab>323`

您也可以使用Perl一行程序来代替grep响应。grep -P:

perl -ne 'print if /\t/' FILENAME