如何递归查看具有一个字符串且特别是没有其他字符串的文件列表?另外,我的意思是评估文件的文本,而不是文件名。
结论:
根据评论,我最终使用了:
find . -name "*.html" -exec grep -lR 'base\-maps' {} \; | xargs grep -L 'base\-maps\-bot'
此返回的文件带有“base-maps”而不是“base-maps-bot”。谢谢!!
答案 0 :(得分:42)
试试这个:
grep -rl <string-to-match> | xargs grep -L <string-not-to-match>
说明:grep -lr
使grep递归(r)输出包含<string-to-match>
的所有文件的列表(l)。 xargs循环遍历这些文件,在每个文件上调用grep -L
。 grep -L
只会在文件不包含<string-not-to-match>
时输出文件名。
答案 1 :(得分:3)
不需要在上面的答案中使用xargs;你可以做到这样的事情:
find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print
grep -q
表示安静地运行但返回退出代码,表示是否找到匹配项;然后find
可以使用该退出代码来确定是否继续执行其余选项。如果-exec grep -q <string-to-match> {} \;
返回0,则它将继续执行-not -exec grep -q <string-not-to-match>{} \;
。如果它也返回0,它将继续执行-print
,这将打印文件的名称。
正如另一个答案所指出的那样,以这种方式使用find
比grep -Rl
具有主要优势,您只想搜索某种类型的文件。另一方面,如果您确实想要搜索所有文件,grep -Rl
可能更快,因为它使用一个grep
进程为所有文件执行第一个过滤器,而不是单独的{{1}每个文件的进程。
答案 2 :(得分:1)
这些答案似乎与匹配 BOTH 字符串相关。以下命令应该更好:
grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'
答案 3 :(得分:1)
这是一个更通用的结构:
find . -name <nameFilter> -print0 | xargs -0 grep -Z -l <patternYes> | xargs -0 grep -L <patternNo>
此命令输出名称与<nameFilter>
匹配的文件(根据需要调整find
谓词),其中包含<patternYes>
但不包含<patternNo>
。
增强功能包括:
如果您不需要按名称进行过滤(通常需要考虑当前目录中的所有文件),您可以删除find
并将-R
添加到第一个grep
:
grep -R -Z -l <patternYes> | xargs -0 grep -L <patternNo>
答案 4 :(得分:0)
查找。 -maxdepth 1-名称“ * .py” -exec grep -L“字符串不匹配” {} \;
此命令将在同一目录中获取所有不包含“字符串不匹配”的“ .py”文件。
答案 5 :(得分:0)
要匹配字符串A并排除在我使用的同一行中出现的字符串B和C,并加上引号以允许搜索字符串包含空格
grep -r <string A> | grep -v -e <string B> -e "<string C>" | awk -F ':' '{print $1}'
说明:grep -r递归过滤输出格式匹配的所有行
文件名:第
行
要从这些行中排除(grep -v)那些还包含-e字符串B或-e字符串C的行。awk用于仅将第一个字段(文件名)使用冒号作为字段分隔符-F < / p>