Shell命令查找包含一个单词但不包含第二个单词的文件

San*_*jje 5 linux shell grep exclude

全部

我的 linux 机器中有以下两个文件,我想找出包含“word1”但不包含“word99”的文件

file1.txt
  word1
  word2
  word3
  word4
  word5

file2.txt
  word1
  word2
  word3
  word99
Run Code Online (Sandbox Code Playgroud)

我一直在对包括“word1”在内的文件使用以下命令,但找不到有关如何修改它以获取包含“word1”但不包含“word99”的文件名的任何信息

find . -name '*.*' -exec grep -r 'word1' {} \; -print > output.txt
Run Code Online (Sandbox Code Playgroud)

任何指针都会有所帮助。

谢谢桑迪

San*_*ios 5

    $ grep -lr 'word1' * | xargs grep -L 'word99'
    file1.txt
Run Code Online (Sandbox Code Playgroud)

在哪里:

    -l, --files-with-matches
         Only the names of files containing selected lines are written
         to standard output.
    -R, -r, --recursive
         Recursively search subdirectories listed.
    -L, --files-without-match
         Only the names of files not containing selected lines are written
         to standard output.
Run Code Online (Sandbox Code Playgroud)

在管道之前的命令的第一部分中,我们得到:

    $ grep -lr 'word1' * 
    file1.txt
    file2.txt
Run Code Online (Sandbox Code Playgroud)

上述命令递归地解析子目录中的文件,并列出包含单词word1iefile1.txt和的文件file2.txt

在第二部分的后面| xargs grep -L 'word99',管道发送file1.txtfile2.txt作为输入,xargs将它们grep作为参数提供。grep然后列出不包含word99using-L选项的文件,即file1.txt.

我们需要xargs这里,因为在命令的第一部分,我们将file1.txtfile2.txt作为标准输出的输出。我们需要解析这些文件的内容,而不是字符串file1.txtfile2.txt.

以下命令也给出了相同的结果(与我们搜索/排除字符串的方式相反):

      $ grep -Lr 'word99' * | xargs grep -l 'word1'
      file1.txt
Run Code Online (Sandbox Code Playgroud)


Joh*_*024 0

这会找到包含以下内容的文件word1

$ find . -name '*.*' -type f -exec grep -q 'word1' {} \; -print
./file1.txt
./file2.txt
Run Code Online (Sandbox Code Playgroud)

这会找到包含word1不包含以下 word99内容的文件:

$ find . -name '*.*' -type f -exec grep -q 'word1' {} \; '!' -exec grep -q 'word99' {} \; -print 
./file1.txt
Run Code Online (Sandbox Code Playgroud)

要将输出保存在文件中:

find . -name '*.*' -type f -exec grep -q 'word1' {} \; '!' -exec grep -q 'word99' {} \; -print >output.txt
Run Code Online (Sandbox Code Playgroud)

-exec grep -q word99 {} \;对于带有word99. 我们把!它放在前面来否定返回值。因此,! -exec grep -q word99 {} \;对于没有word99. 位于!单引号中,因为如果打开历史扩展,则!可以是 shell 活动字符。

笔记:

  1. -q添加该选项是grep为了使其安静。使用-q,grep 将设置正确的退出代码,但它不会在标准输出上显示匹配的行。

  2. -type f添加了测试,以便find它仅返回常规文件的名称。