grep으로 정확한 문자열 찾기


9

예를 들어, 전자 메일 주소가 많은 큰 텍스트 파일을 bash를 사용하여 전자 메일이 존재하는지 (또는 없음) 검색 / 확인해야합니다. "앵커"만 사용해야합니까?

grep '^user1@example.com' text_file

아니면 더 좋은 방법이 있습니까? bash 스크립트를 만들어야하며 안전하고 싶습니다.


1
이메일은 한 줄의 유일한 단어입니까?
glenn jackman

실제로 : 파일 형식은 다음과 같습니다. user1@example.com example.com/user1
Pol Hallen

1
이 경우 grep -q '^user1@example\.com\>'시작 부분에 줄 앵커를 사용 하고 끝 부분에 단어 끝 앵커를 사용합니다.
glenn jackman

답변:


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

스테판, 왜 <리다이렉터를 사용하여 파일 입력 (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
-mGNU 전용입니다. -q그러한 행이 있는지 효율적으로 확인 하려면 POSIX를 사용하십시오 .
Stéphane Chazelas

3

이메일 확인이 많이 있습니다. 그 중 하나는 다음과 같습니다.

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

내 대답을 정교하게합니다.

^문자열의 시작을 나타내는 앵커를 사용하고 있습니다. 이메일 주소가 긴 문자열 사이에 있으면 일치하지 않습니다.


2
감사. 파일 내의 모든 이메일 주소를 "추출"하는 일반적인 grep 옵션입니다. read EMAIL을 사용하여 이메일 주소를 하나씩 검색 한 다음 grep을 사용하여 확인해야합니다.
Pol Hallen

2

당신의 grep명령으로 시작 모든 일치 ^user1@example.com뿐만 아니라, 이메일 주소 자체를 포함하여, user1@example.com.spammer.com. 이후 .모든 키와 일치하는 정규 표현식의 특수 문자가, 당신은 그것을 탈출한다\.

텍스트 파일에 한 줄에 하나의 주소가 있다고 가정하면 다음을 사용하십시오.

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

후행 $은 이메일 주소 다음에 줄이 끝나는 지 확인합니다. 나는 또한 큰 따옴표를 사용하고 "이러한 (작은 따옴표는 달리 변수를 사용할 수 있도록 같이 ')


1
또한 일치 user1@example-com합니다.
Stéphane Chazelas

@ StéphaneChazelas 물론입니다; 답변을 업데이트했습니다.
umläute

@ umläute 백 슬래시를 두 배로 늘려야합니다. 그러나를 사용하는 것이 좋습니다 -Fx.
vinc17

@ vinc17, doh; 배쉬 탈출; 어쨌든, 예, 사용하는 것이 더 낫지 -Fx
스테판

0

일반적인 리터럴 / 정확한 문자열 일치를 고려하십시오.

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

#\b shows boundaries over here.

또는,

 grep  "\bsearch_word\b"  <file>  >  output.txt 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.