Найдите точную строку с grep

в качестве примера у меня есть большой текстовый файл со многими адресами электронной почты, используя bash. Мне нужно найти / проверить, существует ли электронное письмо (или нет). Должны ли использоваться (только) «анкеры»?

grep '^user1@example.com' text_file 

или есть лучшие способы? Мне нужно создать сценарий bash, и я хотел бы быть в безопасности.

См. -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 

Чтобы быть максимально эффективным, вы хотите остановиться после того, как будет найдено первое совпадение. Если у вас есть GNU grep , вы можете сделать это:

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

Если вы этого не сделаете, вы можете использовать Perl:

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

Там много чеков электронной почты. Один из них:

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

Выяснить свой ответ.

Вы используете ^ которая указывает начало строки. Это не будет соответствовать, если адрес электронной почты находится где-то между длинной строкой.

ваша команда grep будет соответствовать всем, что начинается с ^user1@example.com , включая сам адрес электронной почты, а также user1@example.com.spammer.com . так как . является специальным символом в регулярных выражениях, который соответствует любому ключу, вы должны избегать его как \.

предполагая, что ваш текстовый файл содержит по одному адресу в строке, используйте:

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

конечный $ будет считать, что строка заканчивается после адреса электронной почты. я также использую двойные кавычки " , поскольку они позволяют использовать переменные (в отличие от одиночных кавычек)

Учитывая общую литеральную / точную строку:

 grep -w "search_word" <file> > output.txt #\b shows boundaries over here. 

или,

  grep "\bsearch_word\b" <file> > output.txt