패턴과 일치하는 줄과 다른 패턴과 일치하는 그 뒤의 모든 줄을 삭제합니다.

패턴과 일치하는 줄과 다른 패턴과 일치하는 그 뒤의 모든 줄을 삭제합니다.

이전에 누군가가 이 질문을 했는지 확실하지 않다는 점부터 시작하겠습니다. 저는 답변을 찾기 위해 인터넷 검색을 했지만 찾지 못했습니다.

표준 Linux/Unix 명령(FreeBSD에서 실행)을 사용하여 로그 파일에서 패턴과 일치하는 행을 제외하고 싶습니다. 로그 파일에는 로그 항목을 압축하기 위한 "마지막 메시지가 x회 반복됨"도 포함되어 있습니다.

예를 들어 저는 다음과 같은 말을 하고 싶습니다:

May 27 2023 11:07 relevant information #1
May 27 2023 11:07 relevant information #2
May 27 2023 11:08 last message repeated 3 times
May 27 2023 11:08 useless information #1
May 27 2023 11:08 last message repeated 5 times
May 27 2023 11:09 last message repeated 8 times
May 27 2023 11:09 relevant information #3
May 27 2023 11:09 useless information #2
May 27 2023 11:10 useless information #3
May 27 2023 11:10 last message repeated 6 times

다음 출력을 얻습니다.

May 27 2023 11:07 relevant information #1
May 27 2023 11:07 relevant information #2
May 27 2023 11:08 last message repeated 3 times
May 27 2023 11:09 relevant information #3

이 작업을 수행하기 위해 sed 명령을 사용했지만 이를 알아내는 데 어떻게 작동하는지 잘 모르겠습니다. 나는 특히 여러 개의 "마지막 메시지 반복"이 이어지는 로그 줄을 잃어버렸습니다. 제가 현재 작업하고 있는 작업은 다음과 같습니다.

sed '/useless information/{d;N;/last message repeated/d;}' ./logfile.txt

위의 방법은 먼저 "쓸모 없는 정보"가 포함된 일치하는 행을 제거한 다음 네임스페이스에 다음 행을 추가합니다 N. 그런 다음 결과 행에 "마지막 메시지 중복"이 포함되어 있으면 제거해야 합니다. 하지만 "쓸모없는 정보"가 있는 행만 삭제합니다.

답변1

쓸모없는 정보 대신 관련 정보를 테스트할 수 있다면 모든 Unix 시스템의 모든 쉘에서 awk를 사용하세요.

awk '/last message repeated/ && f; {f=/relevant information/} f' file
May 27 2023 11:07 relevant information #1
May 27 2023 11:07 relevant information #2
May 27 2023 11:08 last message repeated 3 times
May 27 2023 11:09 relevant information #3

답변2

그리고 pcregrep:

$ pcregrep -vM 'useless information(.*\n.*message repeated)*' your-file
May 27 2023 11:07 relevant information #1
May 27 2023 11:07 relevant information #2
May 27 2023 11:08 last message repeated 3 times
May 27 2023 11:09 relevant information #3

-Mpcregrep의 여러 줄 모드는 M정규식 일치에 필요한 대로 추가 줄을 패턴 공간(한계 내)으로 가져옵니다 . 활성화되면 perl/PCRE 플래그가 활성화됩니다 ( 주제의 시작/끝이 아니라 m주제 내 모든 줄의 시작/끝에서 ^일치함 ). 플래그( 또한 일치하는 개행을 만듭니다)$s.아니요이것을 활성화하면 .*위의 것들이 욕심에도 불구하고 전체 입력을 삼키지 않는 이유를 설명합니다.

의 경우 sed다음과 같을 수 있습니다.

sed -n '
  :start
  /useless information/ {
    :more
    n
    /message repeated/ b more
    b start
  }
  p'

그리고 awk:

awk '! (useless && /message repeated/ || \
        (useless = /useless information/))'

(...)busybox에 할당 하려면 최소한 가 필요합니다 .uselessawk

다음과 동일 perl:

perl -ne 'print unless $useless and /message repeated/ or
            $useless = /useless information/'

( and/ or대신 &&/를 사용하세요 . 괄호를 제거해야 하는 것 ||보다 우선순위가 낮기 때문입니다 . 참고 자료를 참조하세요.)=perldoc perlop

답변3

Raku(이전 Perl_6) 사용

~$ raku -ne '.put unless my $useless and /message \s repeated/ or $useless = /useless \s information/;'  file

#OR

~$ raku -ne '.put unless my $useless and / "message repeated" / or $useless = / "useless information" /;'  file

#OR

~$ raku -ne '.put unless my $useless and m:s/message repeated/ or $useless = m:s/useless information/;'  file 

@Stéphane Chazelas의 훌륭한 Perl 답변을 각색하여 Raku로 번역했습니다. Raku는 유출된 내용에 대해 더 구체적입니다 put. 여기에는 한 줄씩 텍스트가 로드된 테마 변수의 약어가 있습니다 .put. (또한 개행 종결자가 추가되었습니다.)$_.put$_put

두 번째 차이점은 기본적으로 정규식 일치 프로그램의 공백은 중요하지 않다는 것입니다. 따라서 (첫 번째 예에서) message \s repeated입력이 일치하고 큰따옴표로 묶인 문자열도 일치합니다 "message repeated".

그러나 따옴표가 message repeated없거나 따옴표가 없는 경우 모두 useless information많은 수의 오류와 일치하지 않습니다.

Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)

이것이 위의 두 번째와 세 번째 코드 예제의 기원입니다.

https://docs.raku.org/언어/regexes#Sigspace
https://docs.raku.org/routine/put
https://raku.org

관련 정보