如何grep包含行上两个输入字的行? 我正在寻找包含两个单词的行,我该怎么做? 我试过像这样的管子:
1
| grep -c"word1" | grep -r"word2" logs |
它只是在第一个管道命令后卡住了。
为什么?
-
可能重复如何使用grep匹配string1和string2?
你为什么通过-c?这只会显示比赛的数量。同样,没有理由使用-r。我建议你阅读man grep。
要在同一行上查找2个单词,只需执行以下操作:
1
| grep"word1" FILE | grep"word2" |
grep"word1" FILE将从FILE打印其中包含word1的所有行,然后grep"word2"将打印其中包含word2的行。因此,如果使用管道组合这些,它将显示包含word1和word2的行。
如果您只想计算同一行上2个单词的行数,请执行以下操作:
1
| grep"word1" FILE | grep -c"word2" |
另外,要解决您的问题,为什么会卡住:在grep -c"word1"中,您没有指定文件。因此,grep期望从stdin输入,这就是它似乎挂起的原因。您可以按Ctrl + D发送EOF(文件结束),以便退出。
-
当您感到困惑时,手册页几乎是您想要澄清的最后一个位置。他们比随机猜测更令人困惑。
-
@TotalFrickinRockstarFromMars:我不同意。确实,在开始时它们可能看起来令人困惑,但是一旦习惯了使用它们的格式就非常简单了。无论如何,我把它包含在答案中更多的是为了"教一个人怎么钓鱼"一点,我预计OP不会知道它们,而且man page可以变得非常方便。
-
@houbysoft然后我们必须同意不同意。在8年的大部分时间里,我一直在使用Linux和朋友,而且我仍然宁愿谷歌而不是使用手册页。
-
@TotalFrickinRockstarFromMars:嗯,我不否认使用它。无论如何,你能指出一些你在grep手册页中发现"令人困惑"的具体事情吗?
-
@houbysoft:如果我需要做计数怎么办?
-
@ user157195:见编辑,grep"word1" FILE | grep -c"word2"。
-
"你能指出一些你在grep手册页中发现'令人困惑'的具体事情吗?" - 令人困惑的是他们为什么不包含简单的例子;)。我认为更广泛的问题是Linux实用程序会向您提供选项,然后提供单字母别名,以便在互联网上为每个人简洁加密,然后通过谷歌搜索命令所做的事情来对其进行解密。
-
我不得不说谷歌搜索有用的唯一原因是因为有好的手册页和有经验的人可以解释它们(或者被迫这样做)。 @corsiKa
-
@geneorama当然,但也许那些开始写作的人会编写更好的手册页,这不会是一个问题。手册页是为已经了解该工具的人编写的,只需要一点提醒。它们不是为那些试图弄清楚他们正在做什么的人而写的。
-
我正在使用GNU grep 3.1。命令:grep"string1"FILE | grep"string2"只找到string2。
处方
在问题中一个简单的重写命令是:
1
| grep"word1" logs | grep"word2" |
第一个grep从文件'logs'中找到带有'word1'的行,然后将它们输入到第二个grep中,它查找包含'word2'的行。
但是,没有必要使用这样的两个命令。您可以使用扩展grep(grep -E或egrep):
1
| grep -E 'word1.*word2|word2.*word1' logs |
如果你知道'word1'将在行上的'word2'之前,你甚至不需要替代方案,而常规grep会做:
1
| grep 'word1.*word2' logs |
"一个命令"变体的优点是只有一个进程在运行,因此包含"word1"的行不必通过管道传递给第二个进程。这有多重要取决于数据文件的大小以及多少行匹配'word1'。如果文件很小,性能可能不是问题,运行两个命令就可以了。如果文件很大但只有几行包含'word1',则管道上传递的数据不会太多,并且使用两个命令就可以了。但是,如果文件很大并且经常出现'word1',那么您可能会将大量数据传递到管道中,而单个命令可以避免这种开销。相反,正则表达式更复杂;您可能需要对其进行基准测试以找出最佳效果 - 但前提是性能确实很重要。如果运行两个命令,则应该在第一个grep中选择不常出现的单词,以最小化第二个处理的数据量。
诊断
最初的脚本是:
1
| grep -c"word1" | grep -r"word2" logs |
这是一个奇怪的命令序列。第一个grep将计算其标准输入上"word1"的出现次数,并在其标准输出上打印该数字。直到你指示EOF(例如通过键入Control-D),它将坐在那里,等待你输入内容。第二个grep在目录logs下面的文件中对'word2'进行递归搜索(或者,如果它是文件,则在文件logs中)。或者,在我的情况下,它将失败,因为既没有文件也没有名为logs的目录,我正在运行管道。请注意,第二个grep根本不读取其标准输入,因此管道是多余的。
使用Bash,父shell会一直等到管道中的所有进程都退出,所以它会等待grep -c完成,直到你指示EOF才会这样做。因此,您的代码似乎陷入困境。使用Heirloom Shell,第二个grep完成并退出,shell再次提示。现在你有两个进程正在运行,第一个grep和shell,它们都试图从键盘读取,并且它不确定哪一个获得任何给定的输入行(或任何给定的EOF指示)。
请注意,即使您输入数据作为第一个grep的输入,您也只能获得输出中包含"word2"的任何行。
脚注:
有一段时间,答案是:
1 2
| grep -E 'word1.*word2|word2.*word1'"$@"
grep 'word1.*word2'"$@" |
这引发了以下评论。
-
有什么用"$ @"可以解释一下。您没有提到任何文件名。
-
@PrabhatKumarSingh:在shell脚本中,"$@"扩展为传递给shell脚本的所有参数(尚未移除)。它可以是文件名列表,也可以是空的,在这种情况下,grep将从标准输入读取。问题中的原始代码也没有提到任何文件名。因此,它将从标准输入读取。
-
好吧,我理解$ @在shell脚本中的意思,但是我没有看到你的答案中提到的脚本,这就是为什么感到困惑。
-
加1可以更有效地执行grep grep。
-
这个解决方案的另一个好处是它可以在两个单词相同的情况下工作,这意味着它还可以检测一个单词是否在一行中重复。已接受的解决方案无法处理此案例。 +1。
-
如果使用--color=auto标志,此解决方案还会以比使用两个greps时更好的方式突出显示结果。
你可以使用awk。像这样...
1
| cat <yourFile> | awk '/word1/ && /word2/' |
订单并不重要。所以,如果你有一个文件,...
一个名为file1的文件包含:
1 2 3 4
| 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 |
然后,
1
| /tmp$ cat file1| awk '/word1/ && /word2/' |
会导致,
1 2
| word1 is in this file as well as word2
word2 is in this file as well as word1 |
是的,awk比较慢。
-
无用的cat(1)
-
单个Awk仍然可能比两个单独的grep进程更快。 (但当然,额外无用的cat过程会或多或少地消除这种差异。)
主要问题是你没有提供任何输入的第一个grep。您需要重新排序命令
1
| grep"word1" logs | grep"word2" |
如果你想计算出现次数,那么在第二个grep上放一个'-c'。
你试试下面的命令
1
| cat log|grep -e word1 -e word2 |
-
这些命令至少搜索一个单词,而不是全部。和猫|是不必要的,你可以将文件作为grep最后一个参数
-
可能没用猫了?!
grep word1 file_name | grep word2
这对我来说似乎是最简单的方法
使用grep:
1
| grep -wE"string1|String2|...." file_name |
或者您可以使用:
1
| echo string | grep -wE"string1|String2|...." |
git grep
以下是使用git grep使用布尔表达式组合多个模式的语法:
1
| git grep -e pattern1 --and -e pattern2 --and -e pattern3 |
上面的命令将打印一次匹配所有模式的行。
如果文件不受版本控制,请添加--no-index param。
Search files in the current directory that is not managed by Git.
检查man git-grep以获取帮助。
也可以看看:
-
如何使用grep匹配string1和string2?
-
检查文件中是否存在多个字符串或正则表达式。
-
如何使用多个AND模式运行grep?
-
有关存储在文件中的多种模式,请参阅:一次匹配文件中的所有模式。