我有一个声明
这是这个管道:
find . | grep -i "Test_" | xargs cat | grep -i "start-node name="
产生如下输出:
<start-node name="Start" secure="false"/>
<start-node name="Run" secure="false"/>
我希望得到的是:
filename1-<start-node name="Start" secure="false"/>
filename2-<start-node name="Run" secure="false"/>
答案 0 :(得分:0)
由于您cat
将所有文件合并为一个流,grep
没有任何文件名信息。您希望将所有文件名作为参数提供给grep
:
find ... | xargs grep "<start-node name=" /dev/null
请注意另外两项更改 - 我已删除-i
标记,因为您似乎正在检查XML,并且不会出现不区分大小写的情况。我已将/dev/null
添加到文件列表中,因此grep
始终至少有两个输入文件,即使find
仅提供一个结果。这是获得grep
打印文件名的便携方式。
现在,让我们看看find
命令。我们可以使用GNU grep的grep
谓词,而不是查找所有文件,然后通过-iregex
进行过滤:
find . -iregex '.*Test_.*' \( -type 'f' -o -type 'l' \) | xargs grep ...
混合大小写模式表明您的文件名不是非常不区分大小写的,您可能不想grep符号链接(我确定您不希望目录和特殊文件通过) ,在这种情况下,您可以简化(并可以再次使用可移植的find
):
find . -name '*Test_*' -type 'f' | xargs grep ...
现在可以防止那些绊倒管道的文件名,而且你有
find . -name '*Test_*' -type 'f' -print0 \
| xargs -0 grep -e "<start-node name=" -- /dev/null
或者,如果你有GNU grep,你根本不需要find
:
grep --recursive --include '*[Tt]est_*' -e "<start-node name=" .
答案 1 :(得分:-1)
如果您只需要计算它们:
find . | grep -i "Test_" | xargs cat | grep -i "start-node name=" | awk 'BEGIN{n=0}{n=n+1;print "filename" n "-" $0}'
答案 2 :(得分:-1)
来自man grep
:
-H Always print filename headers with output lines.