파일에 규칙적으로 반복되는 패턴이 포함된 대용량 파일이 있는데 특정 값이 발생한 후 특정 패턴만 추출하고 다음 값을 추출하고 싶습니다.질소좋아요.
여기에 예가 있지만 이전 숫자는 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
이것은 계산을 위해 보관 공간을 사용합니다.
일치하는 줄이 나타날 때마다 PATTERN
e는 x
버퍼를 변경하고 해당 줄이 있는지 확인합니다.N-1\n
버퍼에 줄바꿈 문자를 유지합니다. 검사가 성공하면 x
다시 변경되어 다음 항목을 가져옵니다.중간 사이즈$!N
명령을 사용하여 p
패턴 공간을 인쇄한 다음 q
uits를 인쇄합니다.
그렇지 않으면 \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번째 일치 항목을 얻으려면
head
및tail
/또는을 사용하십시오 (참조sed
여기) - 검역여행번호 N을 이용하세요
cut
head
및tail
(또는 )를 다시 사용하여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