我如何在Unix平台上的文件中使用 grep tab(\ t)?
grep
如果使用GNU grep,您可以使用Perl样式的正则表达式:
grep -P '\t' *
诀窍是在 single 之前使用$ sign . 它也适用于切割和其他工具 .
grep $'\t' sample.txt
我从来没有设法让'\ t'元字符与grep一起工作 . 但是我发现了两种替代解决方案
使用 <Ctrl-V> <TAB> (按Ctrl-V然后键入tab)
<Ctrl-V> <TAB>
使用awk: foo | awk '/\t/'
foo | awk '/\t/'
来自this answer在Ask Ubuntu上:
告诉grep使用Perl定义的正则表达式(Perl将\ t作为选项卡):grep -P“\ t”<文件名>使用文字制表符:grep“^ V <tab>”<filename>使用printf为您打印制表符:grep“$(printf'\ t')”<filename>
一种方法是(这是与Bash)
grep -P '\t'
-P 打开Perl正则表达式,因此\ t将起作用 .
-P
正如用户放松所说,它可能是特定于GNU grep . 如果shell,编辑器或终端允许,可以选择在其中插入一个选项卡 .
这不是您正在寻找的,但可能适用于您的情况
grep '[[:blank:]]'
相当于
grep -P '[ \t]'
所以它会找到Space和Tab .
§ Character classes
请注意,它不会在我的 man grep 中公布,但仍然有效
man grep
$ man grep | grep blank | wc 0 0 0
另一种在表达式中插入选项卡的方法是使用Bash中鲜为人知的 $'\t' 引号:
$'\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`
使用echo为您插入选项卡 grep "$(echo -e \\t)"
grep "$(echo -e \\t)"
基本上有两种解决方法:
在正则表达式语言中,制表符号通常由 \t 原子编码 . 原子由BSD扩展正则表达式(BSD兼容系统上的 egrep , grep -E )以及Perl兼容的RE( pcregrep ,GNU grep -P )支持 .
\t
egrep
grep -E
pcregrep
grep -P
基本正则表达式和Linux扩展RE显然都不支持 \t . 请参考UNIX实用程序手册页以了解它支持哪种正则表达式语言(因此sed(1),awk(1)和pcregrep(1)正则表达式之间的区别) .
因此,在Linux上:
$ grep -P '\t' FILE ...
在BSD一样的系统:
$ egrep '\t' FILE ... $ grep -E '\t' FILE ...
# no tabs for Python please! grep -q ' ' *.py && exit 1
但是,在交互式shell中工作时,您可能需要依赖shell和终端功能在行中键入正确的符号 . 在大多数终端上,这可以通过 Ctrl V 键组合来完成,该组合指示终端按字面意思处理下一个输入字符( V 用于"verbatim"):
Ctrl
V
$ grep '<Ctrl>+<V><TAB>' FILE ...
某些shell可能为命令排版提供高级支持 . 这样,在bash(1)中, $'string' 形式的单词被特别处理:
$'string'
bash$ grep $'\t' FILE ...
请注意,虽然在命令行中很好,但是当脚本移动到另一个平台时,这可能会产生兼容性问题 . 另外,使用特价时请注意引号,详情请咨询bash(1) .
对于Bourne shell(并且不仅仅是),可以使用printf(1)增强的命令替换来模拟相同的行为,以构造正确的正则表达式:
$ grep "`printf '\t'`" FILE ...
grep "$(printf '\t')" 在Mac OS X上为我工作
grep "$(printf '\t')"
使用gawk,将字段分隔符设置为tab(\ t)并检查字段数 . 如果超过1,则有/是标签
awk -F"\t" 'NF>1' file
一个不错的选择是使用'sed as grep'(如本古典sed tutorial中所述) .
sed -n 's/pattern/&/p' file
示例(适用于bash,sh,ksh,csh,..):
[~]$ cat testfile 12 3 1 4 abc xa c a c\2 1 23
[~]$ sed -n 's/\t/&/p' testfile xa c a c\2
[~]$ sed -n 's/\ta\t/&/p' testfile a c\2
1种方式,适用于ksh,dash等:使用printf插入TAB:
grep "$(printf 'BEGIN\tEND')" testfile.txt
答案更简单 . 写你的grep并在引用类型中选项卡键,它至少在ksh中运行良好
grep " " *
我用的是ksh
grep "[^I]" testfile
使用'sed-as-grep'方法,但用个人喜好的可见字符替换选项卡是我最喜欢的方法,因为它清楚地显示了两者哪些文件包含所请求的信息,以及它放在行中的位置:
sed -n 's/\t/\*\*\*\*/g' file_name
如果你想使用行/文件信息或其他grep选项,但也希望看到tab字符的可见替换,你可以通过
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
编辑:显然,上述内容仅对查看文件内容以查找选项卡有用 - 如果目标是将标签作为较大脚本会话的一部分来处理,则这不起任何有用的作用 .
这适用于AIX . 我正在搜索包含 JOINED<\t>ACTIVE 的行
JOINED<\t>ACTIVE
voradmin cluster status | grep JOINED$'\t'ACTIVE vorudb201 1 MEMBER(g) JOINED ACTIVE *vorucaf01 2 SECONDARY JOINED ACTIVE
您可能想要使用 grep "$(echo -e '\t')"
grep "$(echo -e '\t')"
只有 echo 才能解释反斜杠转义 .
echo
这些替代的二元识别方法是完全有效的 . 而且,我真的很喜欢单个二进制字符的语法用法's using awk, as I couldn' t . 但是,也应该可以以POSIX便携方式(即TAB = echo "@" | tr "\100" "\011" )为shell变量赋值,然后以POSIX便携方式从那里随处使用它;同样(即grep "$TAB" filename) . 虽然此解决方案适用于TAB,但在分配中使用另一个所需的二进制值(而不是TAB字符的值为'tr')时,它也可以很好地工作于其他二进制字符 .
echo "@" | tr "\100" "\011"
其他答案中给出的$'\ t'表示法是特定于shell的 - 它似乎在bash和zsh中有效,但不是通用的 .
NOTE: The following is for the fish shell and does not work in bash :
在 fish shell中,可以使用不带引号的 \t ,例如:
fish
grep \t foo.txt
或者可以使用十六进制或unicode符号,例如:
grep \X09 foo.txt grep \U0009 foo.txt
(这些符号对于更深奥的人物有用)
由于这些值必须不加引号,因此可以通过连接组合引用和不引用的值:
grep "foo"\t"bar"
你可以输入
grep \t foo
要么
grep '\t' foo
搜索文件foo中的制表符 . 您可能还可以执行其他转义码,但我只测试了\ n . 虽然它相当耗时,并且不清楚为什么你想要,在zsh中你也可以输入制表符,回到开头,grep并用引号括起选项卡 .
多次查找空格 [[:space:]]*
grep [[:space:]]*'.''.'
会发现这样的事情:
'标签'..
这些是单引号('),而不是double(“) .这是你在grep中进行连接的方法 . = - )
22 回答
如果使用GNU grep,您可以使用Perl样式的正则表达式:
诀窍是在 single 之前使用$ sign . 它也适用于切割和其他工具 .
我从来没有设法让'\ t'元字符与grep一起工作 . 但是我发现了两种替代解决方案
使用
<Ctrl-V> <TAB>
(按Ctrl-V然后键入tab)使用awk:
foo | awk '/\t/'
来自this answer在Ask Ubuntu上:
一种方法是(这是与Bash)
-P
打开Perl正则表达式,因此\ t将起作用 .正如用户放松所说,它可能是特定于GNU grep . 如果shell,编辑器或终端允许,可以选择在其中插入一个选项卡 .
这不是您正在寻找的,但可能适用于您的情况
相当于
所以它会找到Space和Tab .
§ Character classes
请注意,它不会在我的
man grep
中公布,但仍然有效另一种在表达式中插入选项卡的方法是使用Bash中鲜为人知的
$'\t'
引号:(请注意,如果您匹配固定字符串,则可以使用'-F'模式 . )
有时使用变量可以使符号更具可读性和可管理性:
使用echo为您插入选项卡
grep "$(echo -e \\t)"
基本上有两种解决方法:
在正则表达式语言中,制表符号通常由
\t
原子编码 . 原子由BSD扩展正则表达式(BSD兼容系统上的egrep
,grep -E
)以及Perl兼容的RE(pcregrep
,GNUgrep -P
)支持 .基本正则表达式和Linux扩展RE显然都不支持
\t
. 请参考UNIX实用程序手册页以了解它支持哪种正则表达式语言(因此sed(1),awk(1)和pcregrep(1)正则表达式之间的区别) .因此,在Linux上:
在BSD一样的系统:
但是,在交互式shell中工作时,您可能需要依赖shell和终端功能在行中键入正确的符号 . 在大多数终端上,这可以通过
Ctrl
V
键组合来完成,该组合指示终端按字面意思处理下一个输入字符(V
用于"verbatim"):某些shell可能为命令排版提供高级支持 . 这样,在bash(1)中,
$'string'
形式的单词被特别处理:请注意,虽然在命令行中很好,但是当脚本移动到另一个平台时,这可能会产生兼容性问题 . 另外,使用特价时请注意引号,详情请咨询bash(1) .
对于Bourne shell(并且不仅仅是),可以使用printf(1)增强的命令替换来模拟相同的行为,以构造正确的正则表达式:
grep "$(printf '\t')"
在Mac OS X上为我工作使用gawk,将字段分隔符设置为tab(\ t)并检查字段数 . 如果超过1,则有/是标签
一个不错的选择是使用'sed as grep'(如本古典sed tutorial中所述) .
示例(适用于bash,sh,ksh,csh,..):
1种方式,适用于ksh,dash等:使用printf插入TAB:
答案更简单 . 写你的grep并在引用类型中选项卡键,它至少在ksh中运行良好
我用的是ksh
使用'sed-as-grep'方法,但用个人喜好的可见字符替换选项卡是我最喜欢的方法,因为它清楚地显示了两者哪些文件包含所请求的信息,以及它放在行中的位置:
如果你想使用行/文件信息或其他grep选项,但也希望看到tab字符的可见替换,你可以通过
举个例子:
编辑:显然,上述内容仅对查看文件内容以查找选项卡有用 - 如果目标是将标签作为较大脚本会话的一部分来处理,则这不起任何有用的作用 .
这适用于AIX . 我正在搜索包含
JOINED<\t>ACTIVE
的行您可能想要使用
grep "$(echo -e '\t')"
只有
echo
才能解释反斜杠转义 .这些替代的二元识别方法是完全有效的 . 而且,我真的很喜欢单个二进制字符的语法用法's using awk, as I couldn' t . 但是,也应该可以以POSIX便携方式(即TAB =
echo "@" | tr "\100" "\011"
)为shell变量赋值,然后以POSIX便携方式从那里随处使用它;同样(即grep "$TAB" filename) . 虽然此解决方案适用于TAB,但在分配中使用另一个所需的二进制值(而不是TAB字符的值为'tr')时,它也可以很好地工作于其他二进制字符 .其他答案中给出的$'\ t'表示法是特定于shell的 - 它似乎在bash和zsh中有效,但不是通用的 .
NOTE: The following is for the fish shell and does not work in bash :
在
fish
shell中,可以使用不带引号的\t
,例如:或者可以使用十六进制或unicode符号,例如:
(这些符号对于更深奥的人物有用)
由于这些值必须不加引号,因此可以通过连接组合引用和不引用的值:
你可以输入
要么
搜索文件foo中的制表符 . 您可能还可以执行其他转义码,但我只测试了\ n . 虽然它相当耗时,并且不清楚为什么你想要,在zsh中你也可以输入制表符,回到开头,grep并用引号括起选项卡 .
多次查找空格 [[:space:]]*
grep [[:space:]]*'.''.'
会发现这样的事情:
'标签'..
这些是单引号('),而不是double(“) .
这是你在grep中进行连接的方法 . = - )