"term"에 대한 grep 및 "다른 용어"제외


28

용어를 검색하지만 두 번째 용어가있는 줄을 제외시키는 grep 검색을 작성하려고합니다. 여러 -e "pattern"옵션 을 사용하고 싶었지만 작동하지 않았습니다.

다음은 내가 시도한 명령과 생성 된 오류 메시지의 예입니다.

grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory

-v모든 검색어 / 패턴에 적용 된다는 것이 솔기 입니다. 이것이 실행되지만 search term결과에 포함되지 않습니다 .

grep -i -E "search term" -ve "exclude term"

때때로 단어 주위에 줄을 붙잡고 '|'를 사용하여 다음 작업에서 제외하는 경우 제외에 대한 다른 옵션이 있습니까? , 그것은 단지 그 단어를 제거하지만 그 단어에 대한 블록을 제거하지 않습니다
Learner

답변:


40

GREP 표현식에 두 호출이 필요합니다 :

grep -Ei "search term" | grep -Eiv "exclude term"

검색하는 용어가 정규식이 아닌 경우 고정 문자열 일치 ( -F)를 사용하십시오 .

grep -F "search term" | grep -Fv "exclude term"

18

grep을 두 번 호출하지 않으면이를 달성 할 수있는 유일한 방법이 있습니다. 여기에는 PCRE ( Perl Compatible Regular Expressions ) 및 다소 해킹 된 둘러보기 어설 션이 포함 됩니다.

bar 가 포함 된 일치 항목을 제외하고 foo 를 검색하려면 다음을 사용하십시오.

grep -P '(?=^((?!bar).)*$)foo'

작동 방식은 다음과 같습니다.

  • (?!bar)아무것도하지 일치하는 문자열에서 문자를 사용하지 않고 있습니다. 그런 다음 .단일 문자를 소비합니다.

  • ^((?!bar).)*문자열의 시작 ( ^)에서 끝 ( )까지 위를 반복합니다 $. bar특정 지점에서 발생 하면 (?!bar)일치하지 않으므로 실패합니다 .

  • (?=^((?!bar).)*$) 문자열에서 문자를 소비하지 않고 문자열이 이전 패턴과 일치하는지 확인합니다.

  • foo평소와 같이 foo 를 검색합니다 .

단어를 포함하지 않는 문자열과 일치하는 정규식 에서이 해킹을 찾았 습니까? . 에서 바트 Kiers '대답 , 당신은 부정적인보기 미리 작동 방법에 대한 더 자세한 설명을 찾을 수 있습니다.


좋은 해킹. 이 트릭은 Java에서도 작동합니다.
라만

12

한 번에이 작업을 수행하려면 grep 대신 awk를 사용할 수 있습니다.

체재:

echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'

예 :

  • echo "hello there" | awk '/hello/ && !/there/'

아무것도 반환하지 않습니다.

  • echo "hello thre" | awk '/hello/ && !/there/'

반품 : 안녕하세요

  • echo "hllo there" | awk '/hello/ && !/there/'

아무것도 반환하지 않습니다.

여러 패턴의 경우 괄호를 사용하여 그룹화 할 수 있습니다.

예 :

  • echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'

반품 : 안녕하세요

  • echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'

반환 : 안녕 thre

  • echo "hello there" | awk '(/hello/ || /hi/) && !/there/'

아무것도 반환하지 않습니다.

  • echo "hi there" | awk '(/hello/ || /hi/) && !/there/'

아무것도 반환하지 않습니다.


1
그것은 나를 위해 일하지만, 나는 색상 = P 손실
레오 폴 Sanczyk

1
어떤 출력에서 ​​색상? ls를 사용하여 색상을 유지하려는 경우 출력을 구문 분석 할 때마다 "--color = always"인수를 사용하십시오 (또는 텍스트를 구문 분석 할 때 항상 색상이 손실 됨). 예 : ls --color=always | awk '/hello/ && !/goodbye/'
Philip Reese

답변 @Philip에 감사드립니다! 나는 전에 그것을 시도했지만 성공하지 못했습니다. 패턴에 컬러 텍스트가 있으므로 나중에 일치하지 않으므로 패턴에 일종의 컬러 코드를 포함시켜야합니다. 어쨌든, 당신은 grep -RUbuntu 명령 줄을 사용하여 여러 코드 파일에서 가장 빠른 방법입니다 .
Leopoldo Sanczyk

1

내 실험에서 당신이 파이프 당신을 통해 조건을 제외하면 큰 차이를 만들기 위해 심하지 않는 grepsed. Sed에는 로그 파일을 더 잘 필터링하기 위해 자주 사용하는 유용한 텍스트 대체 기능이 있습니다. sed에 꽤 많은 필터를 결합 할 때 sed를 사용할 것입니다.

화장실 /var/log/tomcat/tomcat.2013-01-14.log.1 
  1851725

 / usr / bin / time grep -i -E "(loginmanager)"/var/log/tomcat/tomcat.2013-01-14.log.1 | sed -e "/ login OK / d"-e "/ 로그인 만료 / d"| 화장실
24.05 사용자 0.15 시스템 0 : 25.27 경과 95 % CPU (0avgtext + 0avgdata 3504maxresident) k
0 입력 +0 출력 (0major + 246minor) 페이지 오류 0 스왑
   5614 91168 1186298

 / usr / bin / time grep -i -E "(loginmanager)"/var/log/tomcat/tomcat.2013-01-14.log.1 | sed -e "/ login OK / d"-e "/ 로그인 만료 / d"| 화장실
23.50user 0.16system 0 : 24.48 경과 96 % CPU (0avgtext + 0avgdata 3504maxresident) k
0 입력 +0 출력 (0major + 246minor) 페이지 오류 0 스왑
   5614 91168 1186298

 / usr / bin / time grep -i -E "(loginmanager)"/var/log/tomcat/tomcat.2013-01-14.log.1 | grep -v -e "로그인 OK"-e "로그인 만료"| 화장실
23.08user 0.14system 0 : 23.55 98 % CPU 경과 (0avgtext + 0avgdata 3504maxresident) k
0 입력 +0 출력 (0major + 246minor) 페이지 오류 0 스왑
   5614 91168 1186298

 / usr / bin / time grep -i -E "(loginmanager)"/var/log/tomcat/tomcat.2013-01-14.log.1 | grep -v -e "로그인 OK"-e "로그인 만료"| 화장실
23.50user 0.15system 0 : 25.27 경과 93 % CPU (0avgtext + 0avgdata 3488maxresident) k
0 입력 +0 출력 (0major + 245minor) 페이지 오류 0 스왑
   5614 91168 1186298


3
grep -F대신 런타임을 비교해보고 grep -E필요하지 않으면 사용 -i하지 마십시오.
Thor

1
그러나 당신은 sed;)을 사용하여 예제를 제공하지 않습니다
Benjamin R
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.