Unix 命令列出包含字符串但*不*包含另一个字符串的文件

发布于 2024-10-17 01:34:25 字数 266 浏览 8 评论 0原文

如何递归查看包含一个字符串且不包含另一个字符串的文件列表?另外,我的意思是评估文件的文本,而不是文件名。


结论:

根据评论,我最终使用:

find . -name "*.html" -exec grep -lR 'base\-maps' {} \; | xargs grep -L 'base\-maps\-bot'

这返回了带有“base-maps”而不是“base-maps-bot”的文件。谢谢你!!

How do I recursively view a list of files that has one string and specifically doesn't have another string? Also, I mean to evaluate the text of the files, not the filenames.


Conclusion:

As per comments, I ended up using:

find . -name "*.html" -exec grep -lR 'base\-maps' {} \; | xargs grep -L 'base\-maps\-bot'

This returned files with "base-maps" and not "base-maps-bot". Thank you!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

找回味觉 2024-10-24 01:34:25

试试这个:

grep -rl <string-to-match> | xargs grep -L <string-not-to-match>

解释:grep -lr 使 grep 递归地 (r) 输出包含 的所有文件的列表 (l)。 xargs 循环遍历这些文件,对每个文件调用 grep -Lgrep -L 仅当文件不包含 时才会输出文件名。

Try this:

grep -rl <string-to-match> | xargs grep -L <string-not-to-match>

Explanation: grep -lr makes grep recursively (r) output a list (l) of all files that contain <string-to-match>. xargs loops over these files, calling grep -L on each one of them. grep -L will only output the filename when the file does not contain <string-not-to-match>.

坐在坟头思考人生 2024-10-24 01:34:25

在上面的答案中使用 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 <要匹配的字符串> {} \; 返回 0,然后继续执行 -not -exec grep -q{} \;。如果也返回 0,它将继续执行 -print,打印文件名。

正如另一个答案所指出的,以这种方式使用 find 比 grep -Rl 具有主要优势,在 grep -Rl 中您只想搜索某种类型的文件。另一方面,如果您确实想要搜索所有文件,grep -Rl 可能会更快,因为它使用一个 grep 进程对所有文件执行第一个过滤器,而不是为每个文件使用单独的 grep 进程。

The use of xargs in the answers above is not necessary; you can achieve the same thing like this:

find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print

grep -q means run quietly but return an exit code indicating whether a match was found; find can then use that exit code to determine whether to keep executing the rest of its options. If -exec grep -q <string-to-match> {} \; returns 0, then it will go on to execute -not -exec grep -q <string-not-to-match>{} \;. If that also returns 0, it will go on to execute -print, which prints the name of the file.

As another answer has noted, using find in this way has major advantages over grep -Rl where you only want to search files of a certain type. If, on the other hand, you really want to search all files, grep -Rl is probably quicker, as it uses one grep process to perform the first filter for all files, instead of a separate grep process for each file.

花想c 2024-10-24 01:34:25

这些答案似乎与 BOTH 字符串相匹配。以下命令应该效果更好:

grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'

These answers seem off as the match BOTH strings. The following command should work better:

grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'
匿名。 2024-10-24 01:34:25

这是一个更通用的结构:

find . -name <nameFilter> -print0 | xargs -0 grep -Z -l <patternYes> | xargs -0 grep -L <patternNo>

此命令输出名称与 匹配的文件(根据需要调整 find 谓词),其中包含 < /code>,但不包含

增强功能包括:

  • 它适用于包含空格的文件名。
  • 它允许您按名称过滤文件。

如果您不需要按名称过滤(通常希望考虑当前目录中的所有文件),您可以删除 find 并将 -R 添加到第一个 <代码>grep:

grep -R -Z -l <patternYes> | xargs -0 grep -L <patternNo>

Here is a more generic construction:

find . -name <nameFilter> -print0 | xargs -0 grep -Z -l <patternYes> | xargs -0 grep -L <patternNo>

This command outputs files whose name matches <nameFilter> (adjust find predicates as you need) which contain <patternYes>, but do not contain <patternNo>.

The enhancements are:

  • It works with filenames containing whitespace.
  • It lets you filter files by name.

If you don't need to filter by name (one often wants to consider all the files in current directory), you can strip find and add -R to the first grep:

grep -R -Z -l <patternYes> | xargs -0 grep -L <patternNo>
我不咬妳我踢妳 2024-10-24 01:34:25

寻找 。 -maxdepth 1 -name "*.py" -exec grep -L "字符串不匹配" {} \;

此命令将获取同一目录中不包含“string-not-to-match”的所有“.py”文件。

find . -maxdepth 1 -name "*.py" -exec grep -L "string-not-to-match" {} \;

This Command will get all ".py" files that don't contain "string-not-to-match" at same directory.

半衾梦 2024-10-24 01:34:25

匹配字符串 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

To match string A and exclude strings B & C being present in the same line I use, and quotes to allow search string to contain a space

grep -r <string A> | grep -v -e <string B> -e "<string C>" | awk -F ':' '{print $1}'

Explanation: grep -r recursively filters all lines matching in output format

filename: line

To exclude (grep -v) from those lines the ones that also contain either -e string B or -e string C. awk is used to print only the first field (the filename) using the colon as fieldseparator -F

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文