【发布时间】:2010-10-01 01:14:38
【问题描述】:
如何通过管道将 grep 的输出作为另一个 grep 的搜索模式?
举个例子:
grep <Search_term> <file1> | xargs grep <file2>
我希望第一个 grep 的输出作为第二个 grep 的搜索词。上述命令将第一个 grep 的输出视为第二个 grep 的文件名。我尝试对第二个 grep 使用 -e 选项,但它也不起作用。
【问题讨论】:
如何通过管道将 grep 的输出作为另一个 grep 的搜索模式?
举个例子:
grep <Search_term> <file1> | xargs grep <file2>
我希望第一个 grep 的输出作为第二个 grep 的搜索词。上述命令将第一个 grep 的输出视为第二个 grep 的文件名。我尝试对第二个 grep 使用 -e 选项,但它也不起作用。
【问题讨论】:
你需要使用xargs的-i开关:
grep ... | xargs -ifoo grep foo file_in_which_to_search
这将采用-i(在本例中为foo)之后的选项,并将命令中出现的每个选项替换为第一个grep 的输出。
这与:
grep `grep ...` file_in_which_to_search
【讨论】:
试试
grep ... | fgrep -f - file1 file2 ...
【讨论】:
-”。谢谢!
如果使用 Bash,那么您可以使用反引号:
> grep -e "`grep ... ...`" files
-e 标志和双引号可确保以连字符开头的初始 grep 的任何输出都不会被解释为第二个 grep 的选项。
请注意,双引号技巧(也确保 grep 的输出被视为单个参数)仅适用于 Bash。它似乎不适用于 (t)csh。
还请注意,反引号是将一个程序的输出获取到另一个程序的参数列表的标准方法。并非所有程序都能像 (f)grep 那样方便地从标准输入读取参数。
【讨论】:
我想在当前目录中的文件名(使用 find 找到)中具有特定模式的文件(使用 grep)搜索文本。我使用了以下命令:
grep -i "pattern1" $(find . -name "pattern2")
这里 pattern2 是文件名中的模式,pattern1 是搜索的模式 在匹配pattern2的文件中。
编辑:不是严格意义上的管道,但仍然相关且非常有用...
【讨论】:
这是我用来从列表中搜索文件的方法:
ls -la | grep 'file-in-which-to-search'
【讨论】:
好的,违反规则,因为这不是答案,只是说明我无法让任何这些解决方案发挥作用。
% 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 的差异?
【讨论】:
我试过这个方法,效果很好。
[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]$
【讨论】:
你应该以这样的方式 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
【讨论】:
我发现以下命令可以使用 $() 和括号内的第一个命令让 shell 先执行它。
grep $(dig +short) file
当我得到一个主机名时,我用它在文件中查找一个 IP 地址。
【讨论】: