如何grep
在Unix平台上的文件中制表(\ t)?
如何grep
在Unix平台上的文件中制表(\ t)?
Answers:
如果使用GNU grep,则可以使用Perl样式的regexp:
grep -P '\t' *
-P
期权一无所知。
诀窍是在单引号前使用$符号。它也适用于切割和其他工具。
grep $'\t' sample.txt
zsh
我所知,它也可以正常工作。您能否评论该$
符号的语义是什么?
$'\t'' '
。一个真实的示例显示它也可以与sh(不仅是bash,默认情况下未在Android上安装bash)一起使用busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems
。
我从未设法使grep使用'\ t'元字符。但是,我找到了两种替代解决方案:
<Ctrl-V> <TAB>
(按Ctrl-V,然后键入tab)foo | awk '/\t/'
| awk '/\t/'
解决方案将所有的炮弹,平台和系统的工作。
awk
在这里效果很好,但是在我的机器上使用非常大的文件进行的某些测试中,它比使用慢30%grep -P
。根据用例,这可能是琐碎且无关紧要的,并且awk
对于可读性和可移植性而言可能更好。
一种方法是(这与Bash一起使用)
grep -P '\t'
-P
启用Perl正则表达式,因此\ t将起作用。
正如用户放松所说,它可能特定于GNU grep。另一种方法是,如果外壳程序,编辑器或终端程序允许,则从字面上插入一个选项卡。
在表达式中直接插入制表符的另一种方法是使用$'\t'
Bash中鲜为人知的引号:
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`
基本上有两种解决方法:
(推荐)使用grep(1)支持的正则表达式语法。现代grep(1)支持POSIX 1003.2 regex语法的两种形式:基本(过时)RE和现代 RE。在re_format(7)和regex(7)手册页上分别详细描述了语法,它们分别是BSD和Linux系统的一部分。GNU grep(1)还支持pcre(3)库提供的与Perl兼容的RE。
在正则表达式语言中,制表符通常由\t
atom 编码。由BSD支持的原子扩展正则表达式(egrep
,grep -E
在BSD兼容系统),以及Perl兼容的RE(pcregrep
,GNU 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
但是,在交互式外壳中工作时,您可能需要依赖外壳和终端功能才能在行中键入正确的符号。在大多数终端上,这可以通过Ctrl
+ V
键组合来完成,该组合键指示终端按字面意义对待下一个输入字符(V
“ verbatim”表示):
$ grep '<Ctrl>+<V><TAB>' FILE ...
某些外壳程序可能会提供命令排版的高级支持。这样的形式在bash(1)中的单词$'string'
被特殊对待:
bash$ grep $'\t' FILE ...
但是请注意,尽管在命令行中比较友好,但是当脚本将被移动到另一个平台时,这可能会产生兼容性问题。另外,使用特价商品时请小心引号,有关详细信息,请咨询bash(1)。
对于Bourne shell(不仅如此),可以使用由printf(1)增强的命令替换来模拟相同的行为,以构造适当的正则表达式:
$ grep "`printf '\t'`" FILE ...
+1方式,适用于ksh,破折号等:使用printf插入TAB:
grep "$(printf 'BEGIN\tEND')" testfile.txt
grep "$(printf '\t')" testfile.txt
答案很简单。编写您的grep并在引号中输入tab键,至少在ksh中它能正常工作
grep " " *
使用'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
编辑:显然,以上内容仅适用于查看文件内容以定位选项卡-如果目标是将选项卡作为较大的脚本会话的一部分进行处理,则此功能无用。
查找空格多次[[:space:]] *
grep [[:space:]] *'。''。'
会发现这样的事情:
“标签” ..
这些是单引号('),而不是双引号(“)。
这就是在grep中进行串联的方式。=-)
grep "<Ctrl+V><TAB>"
,它的工作原理:(如果第一次类型grep "
,然后按Ctrl + V组合键,然后按TAB键,然后输入"
并按下回车键,瞧!)