grep을 사용하면 패턴을 일치시키고 다른 패턴을 반전시켜 어떻게 일치시킬 수 있습니까?


11

으로 grep, 나는 패턴과 일치하는 모든 행을 선택하려면, 그것은 또 다른 패턴과 일치하지 않습니다. 옵션 (또는 , 또는 )을 grep사용할 수 있도록 단일 호출을 사용할 수 있기를 원합니다 .--after-context--before-context--context

-v옵션 을 grep사용하여 전달하는 모든 패턴을 무효화하므로 여기에서 실행 가능하지 않습니다 -e.

다음 컨텍스트의 한 줄로 줄 일치 needle를 무시하고 일치하는 줄을 찾고 싶습니다 ignore me.

내 입력 파일은 다음과 같습니다.

one needle ignore me
two
three
four needle
five

내가 원하는 결과는 다음과 같습니다

four needle
five

보시다시피이 순진한 솔루션은 작동하지 않습니다.

$ cat file | grep --after-context=1 needle | grep -v 'ignore me'
two
---
four needle
five

답변:


10

GNU grep 을 가지고 있다면 부정 구조 를 가진 Perl 정규 표현식을 사용할 수 있습니다 .

grep -A1 -P '^(?!.*ignore me).*needle'

GNU grep이 없으면 awk에서 전후 컨텍스트 옵션을 에뮬레이션 할 수 있습니다 .

awk -v after=3 -v before=2 '
/needle/ && !/ignore me/ {
    for (i in h) {
        print h[i];
        delete h[i];
    }
    until = NR + after;
}
{
    if (NR <= until) print $0; else h[NR] = $0;
    delete h[NR-before];
}
END {exit !until}
'

8

GNU 사용하고있는 것 같습니다 . GNU grep을 사용하면 --perl-regex플래그를 전달하여 PCRE를 활성화 한 다음 아래 예와 같이 네거티브 미리보기 어설 션을 제공 할 수 있습니다.

grep --after-context=1 \
--perl-regex '^(?:(?!ignore me).)*needle(?:(?!ignore me).)*$' file.txt
four needle
five

노트의 중요한 것은 여기 즉 (?:(?!STRING).)*이다 STRING[^CHAR]*하는 것입니다CHAR


@ 1_CR ... 선생님 .. 대단해 .. : P 뭔가 웃는 사람ack
Rahul Patil

@RahulPatil. :-), 그렇습니다. GNU grep이 좋습니다.
iruvar

그것은 내가 원하는 것이 아닙니다. 나는 "나를 무시한다"가 "바늘"의 앞이나 뒤에 있든 작동하기를 원한다.
Flimm

@RahulPatil, 고마워, 나는 최신 버전으로 수정했습니다
iruvar

매우 유용한. 특히 문맥이 일치하는 grep의 경우 패턴의 특정 부분없이 밀접하게 일치하는 줄을 제외하려고합니다. 원래 질문에 가깝지만 완전히 동일하지는 않습니다.
gaoithe

2

멀티 라인 IO를 더 잘 처리하므로 awk를 대신 사용하는 것이 좋습니다. 어느 1) 파이프의 GNU AWK에 결과 --\n기록 세퍼레이터, 또는 2) AWK의 매칭을 모두 수행.

옵션 1

<file grep -A1 needle | awk '!/ignore me/' RS='--\n' ORS='--\n'

산출:

four needle                                                                                  
five
--

이 옵션 은 첫 번째 행과 비교하기 위해 전체 레코드에서 ignore me, 설정 FS=1및 일치 를 검색합니다 $1.

옵션 2

<file awk 'a-- > 0; $0 ~ re1 && $0 !~ re2 { print $0; a=after }' re1=needle re2='ignore me' after=1

ignore me파일에 여러 개가 있습니까 , awk 작동하지 않습니다
Rahul Patil

@RahulPatil : 질문을 다시 말하거나 자세하게 설명해 주시겠습니까? 나는 당신이 무엇을 요구하는지 이해하지 못합니다.
Thor

이 입력 파일로 예제를 테스트 @Thos paste.ubuntu.com/6252860
라훌 파틸에게

@RahulPatil : 이제 당신이 의미하는 바를 알았습니다. 옵션 1--\n일치하는 각 그룹 사이에 구분 기호가 있다고 가정합니다 . 그룹이 서로 인접하면 존재하지 않습니다. 인접 그룹을 처리하는 방법은 작업별로 다르므로 반드시 잘못된 것은 아닙니다. 옵션 2 는 분리기에 의존하지 않으며 영향을받지 않습니다.
Thor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.