当前位置: 首页>>技术教程>>正文


Grep在一行中搜索两个单词

, ,

问题描述

我一直试图找到一种方法来过滤一个包含”lemon”和”rice”字样的行。我知道如何找到”lemon”或”rice”而不是其中两个。它们不需要紧挨着另一个,只需要一行文本。

最佳解决方案

“两者在同一行”意味着“’rice’后跟随机字符,然后是’lemon’,或者相反”。

在正则表达式中是rice.*lemonlemon.*rice。您可以使用|将其组合:

grep -E 'rice.*lemon|lemon.*rice' some_file

如果要使用普通正则表达式而不是扩展正则表达式(-E),则需要在|之前使用反斜杠:

grep 'rice.*lemon\|lemon.*rice' some_file

对于更快速变得有点冗长的单词,通常更容易使用grep的多个调用,例如:

grep rice some_file | grep lemon | grep chicken

次佳解决方案

您可以将第一个grep命令的输出传递给另一个grep命令,该命令将匹配这两个模式。所以,你可以这样做:

grep <first_pattern> <file_name> | grep <second_pattern>

要么,

cat <file_name> | grep <first_pattern> | grep <second_pattern>

例:

让我们在文件中添加一些内容:

$ echo "This line contains lemon." > test_grep.txt
$ echo "This line contains rice." >> test_grep.txt
$ echo "This line contains both lemon and rice." >> test_grep.txt
$ echo "This line doesn't contain any of them." >> test_grep.txt
$ echo "This line also contains both rice and lemon." >> test_grep.txt

该文件包含什么:

$ cat test_grep.txt 
This line contains lemon.
This line contains rice.
This line contains both lemon and rice.
This line doesn't contain any of them.
This line also contains both rice and lemon.

现在,让我们想要的是:

$ grep rice test_grep.txt | grep lemon
This line contains both lemon and rice.
This line also contains both rice and lemon.

我们只得到两个模式匹配的行。您可以扩展它并将输出传递给另一个grep命令以进一步进行”AND”匹配。

第三种解决方案

虽然这个问题要求’grep’,但我认为发布一个简单的’awk’解决方案可能会有所帮助:

awk '/lemon/ && /rice/'

除了’and’之外,这可以通过更多单词或其他布尔表达式轻松扩展。

第四种方案

以任何顺序查找匹配的另一个想法是使用:

grep with -P (Perl-Compatibility)选项和正向前瞻性正则表达式(?=(regex))

grep -P '(?=.*?lemon)(?=.*?rice)' infile

或者您可以在下面使用,而不是:

grep -P '(?=.*?rice)(?=.*?lemon)' infile
  • 。*?表示匹配任何字符。出现零次或多次*,而它们是可选的,后跟一个模式(米或柠檬)。的?在它之前使一切都是可选的(意味着所有匹配的零或一次。*)

(?=pattern):正向前瞻:正向前瞻构造是一对括号,左括号后跟一个问号和一个等号。

因此,这将以随机顺序返回包含lemonrice的所有行。此外,这将避免使用|并使grep加倍。


外部链接:Advanced Grep Topics Positive Lookahead – GREP for Designers

第五种方案

grep -e foo -e goo

将返回foo或goo的匹配项

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/2507.html,未经允许,请勿转载。