如何让grep通过NULL字符单独输出?
How to make grep separate output by NULL characters?
假设我们正在对一堆文件进行多行正则表达式模式搜索,并且我们想从 grep 中提取匹配项。默认情况下,grep 输出由换行符分隔的匹配项,但由于我们使用的是多行模式,因此我们无法轻松提取单个匹配项,这造成了不便。
例子
grep -rzPIho '}\n\n\w\w\b' | od -a
根据文件树中的文件,这可能会产生类似于
的输出
0000000 } nl nl m y nl } nl nl i f nl } nl nl m
0000020 y nl } nl nl m y nl } nl nl i f nl } nl
0000040 nl m y nl
0000044
如您所见,我们无法在换行符上拆分以获得匹配项以供进一步处理,因为匹配项本身包含换行符。
什么不起作用
现在 --null
(或 -Z
)只能与 -l
一起使用,这使得 grep 只列出文件名而不是匹配项,所以这对这里没有帮助。
请注意,这不是 Is there a grep equivalent for find's -print0 and xargs's -0 switches? 的重复,因为该问题的要求不同,因此可以使用替代技术来回答。
那么,我们怎样才能让它发挥作用呢?也许将 grep 与其他工具结合使用?
我想到的是使用组分隔符,例如:
grep -rzPIho '}\n\n\w\w\b' $FILE -H | sed "s/^$FILE:/\x0/"
这是另一种方法,它应该比@bufh 发布的更简单,但也更复杂、更慢。
$ grep -rIZl '' --include='*.pl'| xargs -0 cat | dos2unix | tr '\n[=10=]' '[=10=]\n' \
| grep -Pao '}\x00\x00\w\w\b' | tr '[=10=]\n' '\n[=10=]' | od -a
dos2unix 显然只有在使用 windows 行尾时才需要。所以这里的重点是我们用输入中的换行符交换空字节,而不是在空字节上进行 grep 匹配,然后交换回来。
0000000 } nl nl m y nul } nl nl i f nul } nl nl m
0000020 y nul } nl nl m y nul } nl nl i f nul } nl
0000040 nl m y nul
0000044
所以我在 GNU grep 错误邮件列表中将此问题作为功能请求提交,它似乎是代码中的错误。
它已被修复并推送到 master,因此它将在下一个 GNU grep 版本中可用:http://git.savannah.gnu.org/cgit/grep.git/commit/?id=cce2fd5520bba35cf9b264de2f1b6131304f19d2
总结一下:此补丁确保 -z
标志不仅与 -l
结合使用,而且与 -o
.
结合使用
假设我们正在对一堆文件进行多行正则表达式模式搜索,并且我们想从 grep 中提取匹配项。默认情况下,grep 输出由换行符分隔的匹配项,但由于我们使用的是多行模式,因此我们无法轻松提取单个匹配项,这造成了不便。
例子
grep -rzPIho '}\n\n\w\w\b' | od -a
根据文件树中的文件,这可能会产生类似于
的输出0000000 } nl nl m y nl } nl nl i f nl } nl nl m
0000020 y nl } nl nl m y nl } nl nl i f nl } nl
0000040 nl m y nl
0000044
如您所见,我们无法在换行符上拆分以获得匹配项以供进一步处理,因为匹配项本身包含换行符。
什么不起作用
现在 --null
(或 -Z
)只能与 -l
一起使用,这使得 grep 只列出文件名而不是匹配项,所以这对这里没有帮助。
请注意,这不是 Is there a grep equivalent for find's -print0 and xargs's -0 switches? 的重复,因为该问题的要求不同,因此可以使用替代技术来回答。
那么,我们怎样才能让它发挥作用呢?也许将 grep 与其他工具结合使用?
我想到的是使用组分隔符,例如:
grep -rzPIho '}\n\n\w\w\b' $FILE -H | sed "s/^$FILE:/\x0/"
这是另一种方法,它应该比@bufh 发布的更简单,但也更复杂、更慢。
$ grep -rIZl '' --include='*.pl'| xargs -0 cat | dos2unix | tr '\n[=10=]' '[=10=]\n' \
| grep -Pao '}\x00\x00\w\w\b' | tr '[=10=]\n' '\n[=10=]' | od -a
dos2unix 显然只有在使用 windows 行尾时才需要。所以这里的重点是我们用输入中的换行符交换空字节,而不是在空字节上进行 grep 匹配,然后交换回来。
0000000 } nl nl m y nul } nl nl i f nul } nl nl m
0000020 y nul } nl nl m y nul } nl nl i f nul } nl
0000040 nl m y nul
0000044
所以我在 GNU grep 错误邮件列表中将此问题作为功能请求提交,它似乎是代码中的错误。
它已被修复并推送到 master,因此它将在下一个 GNU grep 版本中可用:http://git.savannah.gnu.org/cgit/grep.git/commit/?id=cce2fd5520bba35cf9b264de2f1b6131304f19d2
总结一下:此补丁确保 -z
标志不仅与 -l
结合使用,而且与 -o
.