列出包含字符串但 *NOT* 包含另一个字符串的文件的 Unix 命令
Posted
技术标签:
【中文标题】列出包含字符串但 *NOT* 包含另一个字符串的文件的 Unix 命令【英文标题】:Unix Command to List files containing string but *NOT* containing another string 【发布时间】:2011-06-26 17:55:55 【问题描述】:我如何递归地查看包含一个字符串但没有另一个字符串的文件列表?另外,我的意思是评估文件的文本,而不是文件名。
结论:
根据 cmets,我最终使用:
find . -name "*.html" -exec grep -lR 'base\-maps' \; | xargs grep -L 'base\-maps\-bot'
这返回了带有“base-maps”而不是“base-maps-bot”的文件。谢谢!!
【问题讨论】:
最简单的方法是使用grep -l
列出匹配模式的文件,然后将其通过管道传送到grep -v
。
属于superuser.com
Mikel:但是,它只会将文件名通过管道传递给另一个 grep
,而后者又只能从这些文件名中过滤而不是文件内容。
我已经尝试过了,并且同意 Alan 的观点,即它只过滤文件名。因此,它并没有达到我希望的效果。
@Alan 你不能传递 grep 一个文件集,如果是这样,你不能传递一个基于另一个 grep 的文件集吗?这只是我想象的可能性,但如果有人知道怎么做,那就太棒了:D
【参考方案1】:
试试这个:
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>
时输出文件名。
【讨论】:
grep 字符串应该被引用还是转义?是的,也不是。 另外,有没有一种好方法可以通过仅包含 .html 文件来提高流程效率? @Matrymfind . -name "*.html" -exec grep -l <string-to-match> \; | xargs grep -L <string-not-to-match>
@chrisaycock 添加 R 并转义连字符,这看起来对吗?找 。 -name "*.html" -exec grep -lR 'base\-maps' \; | xargs grep -L 'base\-maps\-bot'
太棒了。太棒了太棒了。【参考方案2】:
在上面的答案中使用 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
进程对所有文件执行第一个过滤器,而不是为每个文件使用单独的grep
进程.
【讨论】:
【参考方案3】:这些答案似乎与 BOTH 字符串匹配。以下命令应该会更好:
grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'
【讨论】:
【参考方案4】:这是一个更通用的结构:
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>
【讨论】:
【参考方案5】:找到 . -maxdepth 1 -name "*.py" -exec grep -L "string-not-to-match" \;
此命令将获取同一目录下所有不包含“string-not-to-match”的“.py”文件。
【讨论】:
【参考方案6】:匹配字符串 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
【讨论】:
请为您的代码添加一点解释以获取更多信息。以上是关于列出包含字符串但 *NOT* 包含另一个字符串的文件的 Unix 命令的主要内容,如果未能解决你的问题,请参考以下文章
核心数据 NSEntityDescription.entityForName 返回 nil,但 managedObjectModel.entities 列出了实体