패턴과 일치하는 n번째 라인과 다음 N라인을 추출합니다.

패턴과 일치하는 n번째 라인과 다음 N라인을 추출합니다.

파일에 규칙적으로 반복되는 패턴이 포함된 대용량 파일이 있는데 특정 값이 발생한 후 특정 패턴만 추출하고 다음 값을 추출하고 싶습니다.질소좋아요.
여기에 예가 있지만 이전 숫자는 members of the group실제로 존재하지 않습니다.

입력하다:

1 members of the group
...
...
2 members of the group
...
...
...
n members of the group
...
...
...

산출:

85 members of the group
...
...
...
...
...

(게임 85 및 다음 5줄)

답변1

방법은 다음과 같습니다 awk.

awk -vN=85 -vM=5 'BEGIN{c=0}
/PATTERN/{c++
{if (c==N) {l=NR;last=NR+M}}
}{if (NR<=last && NR>=l) print}' infile

어디에N질소번째 줄은 다음 줄의 수인 와 PATTERN일치 합니다. M다음과 같은 경우 카운터를 설정합니다.질소3행에서 일치하는 항목을 발견하면 행 번호를 저장합니다. 그런 다음 현재에서 + NR까지 행을 인쇄합니다 .NR중간 사이즈.


기록에 따르면 sed( gnu sed구문)을 사용하는 방법은 다음과 같습니다.

sed -nE '/PATTERN/{x;/\n{84}/{x;$!N;$!N;$!N;$!N;$!N;p;q};s/.*/&\n/;x}' infile

이것은 계산을 위해 보관 공간을 사용합니다.
일치하는 줄이 나타날 때마다 PATTERNe는 x버퍼를 변경하고 해당 줄이 있는지 확인합니다.N-1\n버퍼에 줄바꿈 문자를 유지합니다. 검사가 성공하면 x다시 변경되어 다음 항목을 가져옵니다.중간 사이즈$!N명령을 사용하여 p패턴 공간을 인쇄한 다음 quits를 인쇄합니다.
그렇지 않으면 \n예약된 공간에 다른 ewline 문자를 추가한 다음 x다시 변경합니다.
이 솔루션은 금방 번거로워질 수 있으므로 그다지 편리하지 않습니다.중간 사이즈는 큰 숫자이며 스크립트를 printf작성하려면 약간의 -fu가 필요합니다 sed(패턴은 말할 것도 없고 sed공간을 제한하기 위해 일부 s를 사용함).

답변2

(exec <file.txt; grep -m 85 'PATTERN' | tail -n 1; head -n 5)

물론 필요에 따라 숫자를 조정할 수 있습니다.

에서 man grep:

   -m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines.  If the  input  is
          standard  input  from a regular file, and NUM matching lines are
          output, grep ensures that the standard input  is  positioned  to
          just  after the last matching line before exiting, regardless of
          the presence of trailing context lines.  This enables a  calling
          process  to resume a search.

grep위 명령은 이 기능이 제대로 작동할 수 있도록 서브쉘을 사용하고 STDIN을 원하는 파일로 설정하여 이 기능을 활용합니다 . 그런 다음 최종(85번째) 인스턴스 캡처를 사용 tail -n 1하고 별도의 호출을 통해 필요한 컨텍스트 줄을 얻을 수 있습니다 head.

이 명령을 사용하면알다파일에 인스턴스가 85개 이상 있습니다.PATTERN;이 경우에는 완벽하게 작동합니다.

그 경우가능한더 적고 명령에 약간의 조정이 필요합니다. 현재 상태에서 요청한 것보다 일치하는 항목이 적으면 후행 컨텍스트 줄 없이 최종 일치 항목을 인쇄합니다.

답변3

주로 정규 표현식을 이해 awk하고 사용 하지 않으면 sed다음과 같이 할 것입니다.

  • grep줄번호를 포함한 패턴을 찾는 데 사용됩니다 . ( -n)
  • 85번째 일치 항목을 얻으려면 headtail/또는을 사용하십시오 (참조sed여기)
  • 검역여행번호 N을 이용하세요cut
  • headtail(또는 )를 다시 사용하여 sed원본 파일의 N번째 줄과 다음 5줄을 가져옵니다.

이 모든 것을 한 줄로 결합할 수 있습니다. 더럽고 느리지만 최소한의 도구 세트로 작동합니다.

다음은 rkhunter.log 파일을 검색하여 세 번째로 나타나는 "basename"과 다음 네 줄을 표시합니다.

 /var/log$ tail rkhunter.log -n +$(grep -n 'basename' rkhunter.log|cut -d: -f1|tail -n +3|head -1)| head -5

편집하다

방금 @Wildcard의 답변을 보았고 전환이 원래 솔루션보다 사용하기가 더 쉽습니다 -m. grep그래서 여기에 다음을 사용하는 또 다른 대답이 있습니다.grep -m

/var/log$ grep -m 3 -A 4 'basename'  rkhunter.log | tail -5

답변4

이것은 내 bash에서 작동합니다.

{ T=85; N=5; c=0; while read line ; do echo "$line" | grep -c "members of the group" > /dev/null && c=$(($c+1)) ; [[ $c -eq $T ]] && { echo "$line"; break ;} ; done ; head -n $N ; } < input_file

관련 정보