如何查找包含两个指定单词的所有行(不区分大小写)?

如何查找包含两个指定单词的所有行(不区分大小写)?

我需要检查文本文件中的任何行是否存在两个(指定的)单词。单词的字符没有限制。例如:

我想找到文本文件中同时包含两个单词“cat”和“elephant”的行(即在同一行;不一定并排):

Cat is smaller than elephant
Elephant is larger than cat
Cats are cute!
Elephants are very strong
Cat and elephants live in different environments
cats are friendly

在前面的示例中,如何找到包含这两个单词的行?

Cat is smaller than elephant
Elephant is larger than cat
Cat and elephants live in different environments

我尝试了 grep 和 awk 但没有希望。问题是有些单词有大写和小写,所以我如何匹配这两个单词,无论它们的字母状态如何!?

答案1

grep

grep -i "cat" file | grep -i "elephant"

Cat is smaller than elephant
Elephant is larger than cat
Cat and elephants live in different environment

中的标志grep是忽略大小写(大写/小写)

 -i, --ignore-case         ignore case distinctions

或者awk

awk 'BEGIN{IGNORECASE=1} /cat/&&/elephant/{print $0}' file

@格伦·杰克曼建议该awk语句可以按如下方式运行:

awk '/cat/&&/elephant/' IGNORECASE=1 file

答案2

$ grep -Fiw cat <file | grep -Fiw elephant
Cat is smaller than elephant
Elephant is larger than cat

我们首先从文件中提取file包含该单词的所有行cat,然后将这些行范围缩小到包含该单词的行elephant

这是使用grep -F -i -wwhere完成的

  • -F使grep将模式视为固定字符串,而不是正则表达式,
  • -i进行grep不区分大小写的匹配,并且
  • -w仅匹配grep完整的单词。

-w选项是以下选项的扩展POSIX 标准grep,但由最常见的grep实现实现。当匹配字符串是较长单词的一部分时,它基本上不允许匹配给定的模式。

请注意,我没有匹配该行

Cat and elephants live in different environment

这是由于s决赛elephants。我也不会匹配该行

elephantiasis is catastrophic

为了同样的原因。

s您想在单词末尾使用复数吗,请使用

$ grep -Eiw 'cats?' <file | grep -Eiw 'elephants?'
Cat is smaller than elephant
Elephant is larger than cat
Cat and elephants live in different environment

在这里,我们在两次调用中使用(扩展)正则表达式而不是固定字符串grep。表达式将匹配s两个单词末尾的可选值。现在我们匹配catand cats(不区分大小写),但不会匹配catnip, catsup, 或scat

答案3

使用 GNU sed:

sed -n '/cat/I {/elephant/I p}' file

或 perl

perl -ne 'print if /cat/i and /elephant/i' file

或单个 grep

grep -i -e 'cat.*elephant' -e 'elephant.*cat' file

答案4

您可以在非 GNU 中awk 使用“穷人”技巧来实现不区分大小写:

awk '/[Cc][Aa][Tt]/ && /[Ee][Ll][Ee][Pp][Hh][Aa][Nn][Tt]/'  文件
其中,正如匹配、、或[aeiou]中的任何一个一样,匹配或—  即“e”的不区分大小写的匹配。aeiou[Ee]Ee

请注意,这种方法(例如全部到目前为止发布在这里的其他答案)将匹配该行

有很多方法可以查一头大象。
因为这个词“ch”包含字符串“cat”。如果你想避免这种情况,请尝试
awk '/(^|\W)[Cc][Aa][Tt](\W|$)/ && /(^|\W)[Ee][Ll][Ee][Pp][Hh][Aa ][Nn][Tt](\W|$)/'  文件
您将每个单词限制为前面有一个非单词字符(或行的开头),后面跟着一个非单词字符(或行的末尾) - \W匹配一个非单词字符(即空格) (或制表符)或其他非字母数字 *特点)。

(我不确定这是否符合 POSIX 标准。)

请注意,现在这将不是匹配

猫和大象生活在不同的环境中
因为“大象”一词与“大象”一词不同。
__________________________
* 在这种情况下,下划线(“_”字符)算作一个字母。

相关内容