我经常在find中使用grep两次,以便在文件中搜索两个模式,如下所示:
find . -name \*.xml | xargs grep -l "<beans" | xargs grep singleton
然后我遇到了带空格的文件,这当然打破了上面的命令。我修改它如下处理空格:
find . -name \*.xml -print0 | xargs -0 grep -l "<beans" | xargs grep singleton
选项-print0告诉find使用print null作为分隔符而不是空格,-0告诉xargs期望null。只要我要查找的文件中没有一个文件在其路径中有空格,但只要它们有空格就会有效。
所以我需要的是一个标志告诉grep打印null作为speartor而不是换行符。
有什么想法吗?
答案 0 :(得分:4)
好问题。您可以使用Z选项使grep -l使用null作为分隔符:
find . -name \*.xml -print0 | xargs -0 grep -lZ "<beans" | xargs grep singleton
您也可以将换行符作为分隔符使用xargs。这应该也适用:
find . -name \*.xml -print0 | xargs -0 grep -l "<beans" | xargs "--delimiter=\n" grep singleton
第一种解决方案虽然更好。
答案 1 :(得分:1)
find . -name "*.xml" -exec grep -q "<beans" {} \; -exec grep -q "singleton" {} \; -print
如果您计划在以后的管道序列中使用这些文件名,就像上面所做的那样,将-print
更改为-print0
答案 2 :(得分:0)
如果您使用GNU Parallel而不是xargs,那么您可以避免处理此问题,因为默认情况下GNU Parallel会在换行符而不是空格上分割。
find . -name \*.xml | parallel grep -l "<beans" | parallel grep singleton
观看介绍视频以了解详情:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
答案 3 :(得分:0)
为了避免空间问题,我使用新行字符作为带有-d选项的xargs的分隔符:
void setup(void) {
memcpy(things, (Thing*[]){ MakeThing(), NULL }, sizeof things);
}
对于两个单独的模式搜索,我使用egrep:
xargs -d '\n' ...
所以我的完整解决方案是:
egrep '(pattern one|pattern two)' ...