举例来说,我有一个包含许多电子邮件地址的大文本文件,使用 bash 我需要搜索/验证电子邮件是否存在(或不存在)。应该(仅)使用“锚点”吗?
grep '^user1@example.com' text_file
Run Code Online (Sandbox Code Playgroud)
或者有更好的方法?我需要创建一个 bash 脚本,我希望安全。
Sté*_*las 25
请参阅-F
(固定字符串,而不是正则表达式)和-x
(精确:匹配整行)选项。
grep -Fx user1@example.com text_file
Run Code Online (Sandbox Code Playgroud)
将相当于:
grep '^user1@example\.com$' text_file
Run Code Online (Sandbox Code Playgroud)
(请记住,这.
是一个匹配任何字符的正则表达式运算符)。
-q
如果您只想检查是否有这样的行,请使用该选项:
grep -Fxq user1@example.com text_file &&
echo yes, that address is in that file.
Run Code Online (Sandbox Code Playgroud)
如果要搜索的行和文件名是可变的:
grep -Fxqe "$email" < "$file"
Run Code Online (Sandbox Code Playgroud)
或者
grep -Fxq -- "$email" < "$file"
Run Code Online (Sandbox Code Playgroud)
你不想要:
grep -Fxq "$email" "$file"
仿佛这会造成问题$email
或$file
与开始-
。
如果文件已排序(在您当前的语言环境中,最好是C
),您可以使用comm
代替来加快速度grep
:
printf '%s\n' user1@example.com | comm -12 - text_file
Run Code Online (Sandbox Code Playgroud)
当您要检查多个电子邮件地址时(例如在另一个排序文件中),优势将变得更加明显:
comm -12 text_file emails_to_check
Run Code Online (Sandbox Code Playgroud)
会比:
grep -Fxf emails_to_check text_file
Run Code Online (Sandbox Code Playgroud)
为了尽可能高效,您希望在找到第一个匹配项后停止。如果你有 GNU grep
,你可以这样做:
grep -m 1 '^user1@example\.com$' your_file
Run Code Online (Sandbox Code Playgroud)
如果没有,您可以使用 Perl:
perl -nlE 'say and last if $_ eq q{user1@example.com}' your_file
Run Code Online (Sandbox Code Playgroud)
那里有很多电子邮件检查。其中之一是:
grep -E -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" text_file
Run Code Online (Sandbox Code Playgroud)
详细说明我的答案。
您正在使用^
指示字符串开头的锚点。如果电子邮件地址位于长字符串之间,则这将不匹配。