在同一行上存在2个字的grep

我如何grep包含两个input单词的行的行? 我正在寻找包含两个单词的行,我该怎么做? 我试过这样的pipe道:

  grep -c“word1”| grep -r“word2”日志

它只是在第一个pipe道命令之后进行。 为什么?

你为什么通过-c ? 这只会显示比赛的数量。 同样,没有理由使用-r 。 我build议你阅读man grep

要查找同一行上存在的两个单词,请执行以下操作:

 grep "word1" FILE | grep "word2" 

grep "word1" FILE将从grep "word1" FILE打印出其中有word1的所有行,然后grep "word2"将打印其中有word2的行。 因此,如果使用pipe道组合它们,将显示包含word1和word2的行。

如果您只需要计算同一行上的两个单词有多less行,请执行以下操作:

 grep "word1" FILE | grep -c "word2" 

另外,为了解决你的问题,为什么会卡住:在grep -c "word1" ,你没有指定一个文件。 因此, grep期望从stdin ,这就是为什么它似乎挂起。 您可以按Ctrl + D发送EOF(文件结束),以便退出。

处方

在这个问题中一个简单的重写命令是:

 grep "word1" logs | grep "word2" 

第一个grep从文件'logs'中find包含'word1'的行,然后将这些行提供给第二个grep ,查找包含'word2'的行。

但是,没有必要使用这样的两个命令。 你可以使用扩展grepgrep -Eegrep ):

 grep -E 'word1.*word2|word2.*word1' logs 

如果你知道'word1'会在'word2'的前面,那么你甚至不需要其他的select,而grep会这样做:

 grep 'word1.*word2' logs 

“一个命令”变体的优点是只有一个进程正在运行,所以包含“word1”的行不必通过pipe道传递给第二个进程。 这个问题的重要程度取决于数据文件的大小和“word1”匹配的行数。 如果文件很小,性能不可能是一个问题,运行两个命令是好的。 如果文件很大,但只有几行包含“word1”,那么在pipe道上传递的数据就不会太多,而使用两个命令就没有问题。 但是,如果文件很大并且“word1”频繁出现,那么您可能会将重要数据传递给pipe道,而单个命令会避免这种开销。 对此,正则expression式更为复杂。 您可能需要对其进行基准testing,以确定哪些是最好的 – 但只有在性能确实非常重要的时候。 如果你运行两个命令,你应该select第一个grep不太经常出现的单词,以减less第二个处理的数据量。

诊断

最初的脚本是:

 grep -c "word1" | grep -r "word2" logs 

这是一个奇怪的命令序列。 第一个grep将在其标准input上计算“word1”的出现次数,并在其标准输出上打印该数字。 在你指出EOF之前(比如通过inputControl-D ),它会坐在那里,等着你input一些东西。 第二个grep在目录logs下面的文件(或者,如果它是一个文件,在文件logs )下执行recursionsearch'word2'。 或者在我的情况下,它会失败,因为没有一个文件,也没有一个名为logs我在运行pipe道的目录。 请注意,第二个grep根本不读取其标准input,所以pipe道是多余的。

用Bash,父shell等待,直到pipe道中的所有进程都退出了,所以它等待grep -c完成,直到你指明EOF为止。 因此,你的代码似乎卡住了。 用Heirloom Shell ,第二个grep完成并退出,shell再次提示。 现在你有两个进程正在运行,第一个grep和shell,它们都试图从键盘上读取,而不是确定哪一个获得任何给定的行input(或任何给定的EOF指示)。

请注意,即使您将数据input为第一个grepinput,您也只能得到输出中显示的任何包含“word2”的行。


脚注:

有一次,答案用了:

 grep -E 'word1.*word2|word2.*word1' "$@" grep 'word1.*word2' "$@" 

这触发了下面的评论。

主要的问题是你没有提供任何input的第一个grep。 你需要重新sorting你的命令

 grep "word1" logs | grep "word2" 

如果要计算出现次数,则在第二个grep上加上'-c'。

你可以使用awk。 喜欢这个…

 cat <yourFile> | awk '/word1/ && /word2/' 

订单不重要。 所以,如果你有一个文件和…

一个名为file1的文件包含:

 word1 is in this file as well as word2 word2 is in this file as well as word1 word4 is in this file as well as word1 word5 is in this file as well as word2 

然后,

 /tmp$ cat file1| awk '/word1/ && /word2/' 

将导致,

 word1 is in this file as well as word2 word2 is in this file as well as word1 

是的,awk比较慢。

你用下面的命令尝试一下

 cat log|grep -e word1 -e word2 

grep word1 file_name | grep word2

这似乎是对我来说最简单的方法

使用grep:

 grep -wE "string1|String2|...." file_name 

或者你可以使用:

 echo string | grep -wE "string1|String2|...." 

要同时input两个单词,请使用以下shell命令:

 eval "</dev/stdin $(printf "|grep '%s'" word1 word2)" FILE 

如果你更频繁地使用它,这可以被定义为一个别名:

 alias grep-all="</dev/stdin $(printf "|grep '%s'" word1 word2)" 

然后运行:

 grep-all FILE 

如果您有多个模式存储在文件中,请参阅:一次匹配来自文件的所有模式 。

另外检查: 如何运行多个AND模式的grep?