특정 문자열이 포함된 줄에 대해 디렉터리 및 해당 하위 디렉터리 내의 모든 파일을 검색하고 싶지만 바로 다음 줄에 다른 특정 문자열이 포함된 결과를 제외하고 싶습니다.
예를 들면 다음과 같습니다.
foo1 searchString bar
foo1 excludeString bar
foo2 searchString bar
something else
foo3 searchString bar
foo3 excludeString bar
foo4 searchString bar
다음을 반환해야 합니다:
foo2 searchString bar
foo3 searchString bar
foo4 searchString bar
-A
여러 줄을 인쇄하고 -v
결과를 제외하는 방법을 알고 있습니다 . 그러나 나의 현재 접근 방식 grep -r -A 1 "searchString" | grep -v "excludeString"
은 분명히 작동하지 않습니다.
일치하는 항목이 발견되면 이전 줄도 삭제해야 한다고 두 번째 grep에 지시하는 방법이 있습니까? 아니면 다른 방법으로 이를 달성할 수 있나요?
성능은 내 가장 큰 관심사가 아닙니다. 명령이 상대적으로 기억하기 쉽다면 좋을 것입니다.
답변1
p
erl c
호환 r
정규식 e
을 사용할 수 있습니다 grep
.
$ pcregrep -M '(searchString.*\n)(?!.*excludeString)' file
foo2 searchString bar
foo3 searchString bar
foo4 searchString bar
0개 이상의 문자 searchString
다음 에 새 줄이 오는 문자 를 검색합니다 ..
*
\n
오직만약 있다면아니요( ) 패턴 옆에 있습니다 ?!
. 여러 줄을 일치시키는 .*excludeString
옵션이 있습니다 .-M
답변2
그리고 sed
:
sed '/searchString/!d;$!N;/\n.*excludeString/!P;D' infile
작동 방식:
/searchString/!d
일치하지 않으면 해당 줄을 삭제searchString
하고 새 줄을 읽고 명령 루프를 다시 시작합니다(즉, 나머지 명령은 실행되지 않습니다).- 라인이 일치하면
searchString
실행sed
하십시오$!N;/\n.*excludeString/!P;D
- 참조여기작동 방식; 차이점은 여기서는 줄이 둘 다 일치하도록 ewline 문자excludeString
뒤의 패턴을 찾고 , 그 뒤에 일치하는 줄이 없으면 and 와 일치하는 줄이 없으면 계속 인쇄한다는 것입니다. 알려진 입력) 행에서 해당 부분을 삭제하고 다음을 실행할 수 있습니다.\n
searchString
excludeString
excludeString
searchString
excludeString
\n.*
sed '/searchString/!d;$!N;/excludeString/!P;D' infile