用grep查找确切的字符串


9

举例来说,我有一个带有许多电子邮件地址的大文本文件,使用bash我需要搜索/验证电子邮件是否存在(或不存在)。应该(仅)使用“锚”吗?

grep '^user1@example.com' text_file

还是有更好的方法?我需要创建一个bash脚本,我想很安全。


1
电子邮件是一行中唯一的单词吗?
glenn jackman 2014年

实际上:该文件具有以下格式:user1@example.com example.com/user1
Pol Hallen

1
在这种情况下,我会使用grep -q '^user1@example\.com\>'-在行首放置一个锚,并在末尾放置一个单词结尾的锚。
glenn jackman 2014年

Answers:


24

请参阅-F(固定字符串,而不是正则表达式)和-x(精确:匹配整行)选项。

grep -Fx user1@example.com text_file

相当于:

grep '^user1@example\.com$' text_file

(请记住,它.是匹配任何字符的正则表达式运算符)。

-q如果只想检查是否有这样一行,请使用该选项:

grep -Fxq user1@example.com text_file &&
  echo yes, that address is in that file.

如果要搜索的行和文件名是变量:

grep -Fxqe "$email" < "$file"

要么

grep -Fxq -- "$email" < "$file"

您不想要:

grep -Fxq "$email" "$file"

因为如果$email或以$file开始会引起问题-

如果文件已排序(最好是在您当前的语言环境中C),则可以使用comm而不是来加快处理速度grep

printf '%s\n' user1@example.com | comm -12 - text_file

当您有多个电子邮件地址需要检查时(例如在另一个排序文件中),该优势将变得更加明显:

comm -12 text_file emails_to_check

会比:

grep -Fxf emails_to_check text_file

AFAIK,grep -Fxq -- "$email" "$file"也可以。
vinc17 2014年

stephane,为什么使用<重定向器将文件输入(由grep处理)切换到stdin ?有什么好处吗?
umläute

@umläute和vinc17。就像我说的那样,它涵盖了以开头的文件名-。即使grep -- "$email" "$file"将是一个名为文件有问题-(其grep对待专门为义标准输入
斯特凡Chazelas

6

为了提高效率,您想在找到第一个匹配项后停止。如果您具有GNU grep,则可以执行以下操作:

grep -m 1 '^user1@example\.com$' your_file

如果不这样做,则可以使用Perl:

perl -nlE 'say and last if $_ eq q{user1@example.com}' your_file

4
-m是GNU特定的。-q如果您想有效地检查是否有这样的行,请使用POSIX 。
斯特凡Chazelas

3

那里有很多电子邮件检查。其中之一是:

grep -E -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" text_file

详细说明我的答案。

您正在使用^表示字符串开头的锚点。如果电子邮件地址介于长字符串之间,则此名称将不匹配。


2
谢谢。这是通用的grep选项,用于“提取”文件中的所有电子邮件地址。我需要使用已读EMAIL逐一搜索电子邮件地址,然后使用grep进行检查。
Pol Hallen 2014年

2

您的grep命令将匹配所有以开头的内容^user1@example.com,包括电子邮件地址本身,也包括user1@example.com.spammer.com。由于.是匹配任何键的正则表达式中的特殊字符,因此您应将其转义为\.

假设您的文本文件每行包含一个地址,请使用:

EMAIL=user1@example\\.com
egrep "^${EMAIL}$" text_file

尾随$将确保该行在电子邮件地址之后结束。我也在使用双引号",因为它们允许使用变量(与单引号不同'


1
那也匹配user1@example-com
斯特凡Chazelas

@StéphaneChazelas你当然是对的;更新了答案。
umläute

@umläute您需要将反斜杠加倍。但是最好使用-Fx
vinc17 2014年

@ vinc17,doh; 扑脱 无论如何,是的,我同意使用更好,-Fx但这是
斯蒂芬

0

考虑一般文字/精确字符串匹配:

grep -w "search_word" <file>  >  output.txt

#\b shows boundaries over here.

要么,

 grep  "\bsearch_word\b"  <file>  >  output.txt 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.