Grep - 如何将文件名连接到每个返回的文件内容行?

时间:2015-08-27 15:47:53

标签: linux shell grep

我有一个声明

  1. 查找一组文件
  2. Cats他们的内容
  3. 然后抓住他们的内容
  4. 这是这个管道:

    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"/>
    

3 个答案:

答案 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.