정규식이 일치할 때까지 아래쪽에서 줄을 추출합니다.

정규식이 일치할 때까지 아래쪽에서 줄을 추출합니다.

이 출력이 있습니다.

[root@linux ~]# cat /tmp/file.txt
virt-top time  11:25:14 Host foo.example.com x86_64 32/32CPU 1200MHz 65501MB
   ID S RDRQ WRRQ RXBY TXBY %CPU %MEM   TIME    NAME
    1 R    0    0    0    0  0.0  0.0  96:02:53 instance-0000036f
    2 R    0    0    0    0  0.0  0.0  95:44:07 instance-00000372
virt-top time  11:25:17 Host foo.example.com x86_64 32/32CPU 1200MHz 65501MB
   ID S RDRQ WRRQ RXBY TXBY %CPU %MEM   TIME    NAME
    1 R    0    0    0    0  0.6 12.0  96:02:53 instance-0000036f
    2 R    0    0    0    0  0.2 12.0  95:44:08 instance-00000372

두 개의 청크가 있는 것을 볼 수 있으며 마지막 청크를 추출하고 싶습니다(첫 번째 청크에 CPU가 모두 0이면 상관없습니다). 간단히 말해서 다음 마지막 줄을 추출하고 싶습니다(참고: 때로는 두 개 이상의 인스턴스가 있습니다. -*) 그렇지 않으면 "tail -n 2"를 사용할 수 있습니다.

1 R    0    0    0    0  0.6 12.0  96:02:53 instance-0000036f
2 R    0    0    0    0  0.2 12.0  95:44:08 instance-00000372

나는 sed/awk/grep과 가능한 모든 것을 시도했지만 원하는 결과에 가까운 것은 없습니다.

답변1

조금 어리석은 느낌이 들지만 다음과 같습니다.

$ tac file.txt |sed -e '/^virt-top/q' |tac
virt-top time  11:25:17 Host foo.example.com x86_64 32/32CPU 1200MHz 65501MB
   ID S RDRQ WRRQ RXBY TXBY %CPU %MEM   TIME    NAME
    1 R    0    0    0    0  0.6 12.0  96:02:53 instance-0000036f
    2 R    0    0    0    0  0.2 12.0  95:44:08 instance-00000372

GNU tac리버스 파일(GNU가 아닌 많은 시스템에서 사용 가능 tail -r), sed로 끝나는 첫 번째 줄까지 선택하세요 . 헤더를 추가 하거나 제거 virt-top할 수 있습니다 .sed 1,2dtail -n +3

또는 awk에서:

$ awk '/^virt-top/ { a = "" } { a = a $0 ORS } END {printf "%s", a}' file.txt 
virt-top time  11:25:17 Host foo.example.com x86_64 32/32CPU 1200MHz 65501MB
   ID S RDRQ WRRQ RXBY TXBY %CPU %MEM   TIME    NAME
    1 R    0    0    0    0  0.6 12.0  96:02:53 instance-0000036f
    2 R    0    0    0    0  0.2 12.0  95:44:08 instance-00000372

모든 행을 변수로 수집하고 로 시작하는 행에서 해당 변수를 지웁니다 virt-top.

파일이 매우 큰 경우 tac+ sed솔루션은 파일의 끝부분만 읽으면 되므로 더 빠르지만 awk+ 솔루션은 파일 전체를 위에서부터 읽습니다.

답변2

ed정규식을 사용하여 검색할 수 있습니다 .위로?pattern?일반적인 방법 /pattern/(현재 위치 위에서 검색) 대신 사용됩니다 . 예를 들어:

$ printf '%s\n' '?ID?+1,$p' q | ed -s file.txt
    1 R    0    0    0    0  0.6 12.0  96:02:53 instance-0000036f
    2 R    0    0    0    0  0.2 12.0  95:44:08 instance-00000372

답변3

입력에 고정된 수의 블록이 있는 경우 다음을 수행할 수도 있습니다.

awk '/^virt-top/ && ++n == 2, 0' <your-file

두 번째 발생virt-top 부터 파일 끝까지의 행을 출력합니다(0 은잘못된, 끝을 의미첫 번째,마지막범위를 찾을 수 없습니다).

답변4

이를 수행하는 또 다른 방법은 다음과 같습니다.

$ sed -e '
   /\n/q
   /virt-top/{h;d;}
   H;$!d;g
   s/\n//;D
' file.txt

결과

1 R    0    0    0    0  0.6 12.0  96:02:53 instance-0000036f
2 R    0    0    0    0  0.2 12.0  95:44:08 instance-00000372

관련 정보