【问题标题】:Pipe output to use as the search specification for grep on Linux管道输出用作 Linux 上 grep 的搜索规范
【发布时间】:2010-10-01 01:14:38
【问题描述】:

如何通过管道将 grep 的输出作为另一个 grep 的搜索模式?

举个例子:

grep <Search_term> <file1> | xargs grep <file2>

我希望第一个 grep 的输出作为第二个 grep 的搜索词。上述命令将第一个 grep 的输出视为第二个 grep 的文件名。我尝试对第二个 grep 使用 -e 选项,但它也不起作用。

【问题讨论】:

标签: linux grep


【解决方案1】:

你需要使用xargs-i开关:

grep ... | xargs -ifoo grep foo file_in_which_to_search

这将采用-i(在本例中为foo)之后的选项,并将命令中出现的每个选项替换为第一个grep 的输出。

这与:

grep `grep ...` file_in_which_to_search

【讨论】:

  • xargs replstr 选项在 OS X 上使用大写 -I
【解决方案2】:

试试

grep ... | fgrep -f - file1 file2 ...

【讨论】:

  • 它使用第一个 grep 的输出作为第二个 grep 的 grep 模式,正如问题所问的那样。
  • @Nathan,它使用第一个 grep 的输出作为 fgrep 模式的输入文件。 “-f -”是告诉unix程序使用标准输入作为输入文件的正常方式,如果它通常需要一个输入文件。传统上,fgrep 是唯一将文件作为输入的 grep,尽管 Gnu 可能修改了其他 grep。
  • 哦...我错过了独立的“-”。谢谢!
【解决方案3】:

如果使用 Bash,那么您可以使用反引号:

> grep -e "`grep ... ...`" files

-e 标志和双引号可确保以连字符开头的初始 grep 的任何输出都不会被解释为第二个 grep 的选项。

请注意,双引号技巧(也确保 grep 的输出被视为单个参数)仅适用于 Bash。它似乎不适用于 (t)csh。

还请注意,反引号是将一个程序的输出获取到另一个程序的参数列表的标准方法。并非所有程序都能像 (f)grep 那样方便地从标准输入读取参数。

【讨论】:

  • 如果第一个 grep 返回多个结果,这可能会出现问题。
  • 我尝试了解决方案,它有效。感谢您提供。
【解决方案4】:

我想在当前目录中的文件名(使用 find 找到)中具有特定模式的文件(使用 grep)搜索文本。我使用了以下命令:

 grep -i "pattern1" $(find . -name "pattern2")

这里 pattern2 是文件名中的模式,pattern1 是搜索的模式 在匹配pattern2的文件中。

编辑:不是严格意义上的管道,但仍然相关且非常有用...

【讨论】:

    【解决方案5】:

    这是我用来从列表中搜索文件的方法:

    ls -la | grep 'file-in-which-to-search'
    

    【讨论】:

      【解决方案6】:

      好的,违反规则,因为这不是答案,只是说明我无法让任何这些解决方案发挥作用。

      % fgrep -f test file
      

      工作正常。

      % cat test | fgrep -f - file
      fgrep: -: No such file or directory
      

      失败。

      % cat test | xargs -ifoo grep foo file 
      xargs: illegal option -- i
      usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]
                   [-L number] [-n number [-x]] [-P maxprocs] [-s size]
                   [utility [argument ...]]
      

      失败。请注意,大写 I 是必需的。如果我使用它,一切都很好。

      % grep "`cat test`" file
      

      有点工作原理,它为匹配的术语返回一行,但它也为每个找不到匹配项的文件返回一行 grep: line 3 in test: No such file or directory

      我是否遗漏了什么,或者这只是我的 Darwin 发行版或 bash shell 的差异?

      【讨论】:

        【解决方案7】:

        我试过这个方法,效果很好。

        [opuser@vjmachine abc]$ cat a
        not problem
        all
        problem
        first
        not to get
        read problem
        read not problem
        
        [opuser@vjmachine abc]$ cat b
        not problem xxy
        problem abcd
        read problem werwer
        read not problem  98989
        123 not problem 345
        345 problem tyu
        
        [opuser@vjmachine abc]$ grep -e "`grep problem a`" b --col
        not problem xxy
        problem abcd
        read problem werwer
        read not problem  98989
        123 not problem 345
        345 problem tyu
        
        [opuser@vjmachine abc]$ 
        

        【讨论】:

          【解决方案8】:

          你应该以这样的方式 grep,只提取文件名,见参数 -l(小写 L):

          grep -l someSearch * | xargs grep otherSearch
          

          因为在简单的 grep 上,输出比文件名更多的信息。例如当你这样做时

          grep someSearch *
          

          您将像这样通过管道传输到 xargs 信息

          filename1: blablabla someSearch blablabla something else
          filename2: bla someSearch bla otherSearch
          ...
          

          将上述任何一行通过管道传递给 xargs 都是无意义的。 但是当您执行 grep -l someSearch * 时,您的输出将如下所示:

          filename1
          filename2
          

          现在可以将这样的输出传递给 xargs

          【讨论】:

            【解决方案9】:

            我发现以下命令可以使用 $() 和括号内的第一个命令让 shell 先执行它。

            grep $(dig +short) file
            

            当我得到一个主机名时,我用它在文件中查找一个 IP 地址。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-16
              • 1970-01-01
              • 2021-09-10
              • 1970-01-01
              • 2018-11-18
              相关资源
              最近更新 更多