Linux와 일치하는 상대 로그 파일이 있습니까?

Linux와 일치하는 상대 로그 파일이 있습니까?

grep로그 파일의 내용을 사용 하거나 일치시키는 방법을 이미 알고 있지만 awk다음을 수행할 수 있는 방법이 있습니까?

  1. 파일의 특정 줄을 일치시키고 결과에 포함시킵니다.
  2. 파일(1.)의 일치하는 줄에서 시작하여 두 번째 문자열이 일치할 때까지 위쪽으로 검색하고 해당 문자열과 그 사이의 모든 줄을 결과에 포함합니다.
  3. 그런 다음 세 번째 일치 항목을 사용하여 일치 항목(1.)에서 시작하여 세 번째 문자열을 일치시키고 해당 문자열과 결과 사이의 모든 줄을 포함하여 검색합니다.

이렇게 하면 검색하려는 내용이 BEGINNING 및 END 컨텍스트에 있는 경우 검색하려는 내용이 발생하는 컨텍스트만 검색할 수 있습니다. 로그 파일은 다음과 같습니다.

<several-1000-lines>
...[BEGINX]
some log a
<several-1000-lines>
...[First-string-i-search-for]
<several-1000-lines>
some log b
...[ENDX]
<several-1000-lines>

그런 다음 검색하면 다음과 같은 결과가 나타납니다 [First-string-i-search-for].

...[BEGINX]
some log a
<several-1000-lines>
...[First-string-i-search-for]
<several-1000-lines>
some log b
...[ENDX]

답변1

$ cat tst.awk
BEGIN {
    beg = "[BEGINX]"
    mid = "[First-string-i-search-for]"
    end = "[ENDX]"
}
index($0,beg) {
    gotBeg = 1
    gotMid = 0
    buf = ""
}
gotBeg {
    buf = buf $0 ORS
    if ( index($0,mid) ) {
        gotMid = 1
    }
    if ( index($0,end) ) {
        if ( gotMid ) {
            printf "%s", buf
        }
        gotBeg = 0
    }
}

$ awk -f tst.awk file
...[BEGINX]
some log a
<several-1000-lines>
...[First-string-i-search-for]
<several-1000-lines>
some log b
...[ENDX]

위의 가정은 다음과 같습니다.

  1. 검색 중인 3개의 문자열은 항상 서로 다른 줄에 나타납니다.
  2. 항상 마지막 BEGINX부터 그 뒤의 첫 번째 ENDX까지 테스트하고 싶습니다.

답변2

grepPCRE 지원과 함께 GNU 사용(Perl 호환 정규식):

grep -Pzo '.*\[BEGINX\](.|\n)*?\[First-string-i-search-for\](.|\n)*?\[ENDX\].*\n' infile

그건:

grep -Pzo '.*BEGINNING(.|\n)*?MIDDLE(.|\n)*?END.*\n' infile

답변3

GNU sed는 범위 연산자를 사용하여 예약된 공간에 블록을 저장합니다. 마지막 줄에서 문자열이 블록에 있는지 확인하여 인쇄할 수 있습니다.

sed -n '
  /\[BEGINX]/!d
  :loop
    H;n
  /\[ENDX]/!bloop
  H;z;x
  /\[First-string-i-search-for]/p
' file

범위 연산자를 사용하면 ,다음과 같이 해결할 수 있습니다.

awk '
  BEGIN { str = "[First-string-i-search-for]" }

  /\[BEGINX]/, /\[ENDX]/ {a[++n]=$0}

  n==1               {seen=0;next}
  n && index($0,str) {seen++;next}
  n && /\[ENDX]/     {flush(seen)}

  function flush(flag,  i) {
    if (flag) for (i=1; i<=n; i++) print a[i]
    n = split("", a, ":")
  }
' file
...[BEGINX]
some log a
<several-1000-lines>
...[First-string-i-search-for]
<several-1000-lines>
some log b
...[ENDX]

관련 정보