使用grep匹配内容中的文件扩展名('* .log'是错误的)

时间:2016-09-13 02:41:16

标签: linux grep

我正在尝试搜索每一行,看看哪些行有 any_filename.log

以下代码无效

find . -print | xargs grep -i *.log
find . -print | xargs grep -i "*.log"
find . -print | xargs grep -i '*.log'

有人知道正确的代码吗?

谢谢你

1 个答案:

答案 0 :(得分:1)

根本不需要*;它在这里没有任何用处。在正则表达式语法中(由grep使用),*表示“前一个字符的0或更多”。当 没有前面的字符时,它就是语法错误。

相比之下,正则表达式中的.表示“匹配任何单个字符”。如果要匹配句点,则需要将其转义或将其放在字符类中,如下所示:

find . -exec grep -i -e '[.]log' -- /dev/null '{}' +

如果该行需要 .log结尾,相反,请将匹配与$锚定:

find . -exec grep -i -e '[.]log$' -- /dev/null '{}' +

注意:

  • *.log是glob语法。 [.]log$是正则表达式(正则表达式)语法中的等效模式。这是两种非常不同的语言。
  • find ... | xargs ...是错误的(包含空格,引号,文字反斜杠等的文件名失败),除非-print0中使用find-0xargs一起使用1}}。这两个都是非POSIX扩展,因此最好在-exec ... {} +中使用符合POSIX的find操作来获取运行尽可能少的子进程的xargs行为,并使用字面上给出的名称。
  • grep ... -- /dev/null成语服务有两个目的:传递/dev/null可确保grep的默认值是在传递至少两个文件时使用的默认值,即使find仅被调用只有一个文件名的特定grep实例。相反,--标志确保所有后续文件名都被视为名称,而不是标志;当以这种方式与find一起使用时并不是绝对必要的(因为所有参数都将以./开头,因此看起来不像可选参数),但仍然是很好的做法。