일치하는 패턴 뒤에 줄의 일부만 반환


109

따라서 파일을 열어서 일치하는 줄을 얻는 데 cat사용 grep하면 처리 할 특정 로그 세트로 작업 할 때만 가능합니다. 라인을 패턴과 일치시키는 방법이 필요하지만, 일치 후 라인의 일부만 반환합니다. 경기 전후의 부분은 지속적으로 다릅니다. 내가 사용하여 연주 한 sedawk,하지만 경기 전 부분을 삭제하거나 경기 후 일부를 반환하거나 라인을 필터링하는 방법을 알아낼 수 없었던 어느 작동합니다. 이것은 필터링 해야하는 라인의 예입니다.

2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.amd64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }

내가 필요한 부분은 "스톨"된 후의 모든 것입니다.

이것의 배경은 무언가가 얼마나 자주 멈추는 지 알 수 있다는 것입니다.

cat messages | grep stalled | wc -l

내가해야 할 일은 특정 노드가 몇 번이나 멈추었는지 알아내는 것입니다 ( "중지"후 각 콜론 앞 부분으로 표시됩니다.) 그냥 grep하면 (예 : 20 :) 소프트 실패한 줄을 반환 할 수 있지만 스톨이 없어서 도움이되지 않습니다. 스톨 된 부분 만 필터링하면 스톨 된 노드에서 특정 노드를 잡을 수 있습니다.

모든 의도와 목적을 위해, 이것은 표준 GNU 코어 유틸리티를 갖춘 freebsd 시스템이지만 도움을 줄 수있는 추가 장비는 설치할 수 없습니다.


@Gilles, Odd 내가 검색했을 때 팝업이 나타나지 않았지만 결국 제목을 사용하지 않았지만 제목 아래 화면에 표시되지 않았습니다. 어쨌든, 제쳐두고, 내가 원하는 곳으로 데려다 줄 수는 있지만, 첫 번째 단어가 아니라 경기 후 전체 줄이 필요하지만 큰 변화는 없을 것입니다.
MaQleod

제목이 빨랐다. 나는 당신을 훔쳤습니다. 테이크 sed솔루션을 특별히 공백 취급하지 않습니다.
Gilles

@Gilles, 그건 내가 어떻게 해야할지 잘 모르겠습니다. 나는 아직도 sed를 배우고있다.
MaQleod


1
@ shaa0601 귀하의 질문을 이해하지 못합니다. 형식이없는 주석에서 따르기가 특히 어렵습니다. 독립적 인 새로운 질문을하십시오.
Gilles

답변:


141

이를위한 표준 도구는 다음과 같습니다 sed.

sed -n -e 's/^.*stalled: //p'

상해:

  • -n 기본적으로 아무 것도 인쇄하지 않음을 의미합니다.
  • -e 뒤에 sed 명령이옵니다.
  • s 패턴 교체 명령입니다.
  • 정규 표현식 ^.*stalled:은 찾고자하는 패턴과 이전 텍스트 ( .*모든 텍스트를 의미 ^하며 처음부터 일치가 줄의 시작 부분에서 시작된다는 의미)와 일치합니다. 경우 참고 stalled:라인에 여러 번 발생, 이번이 마지막 발생을 일치합니다.
  • 일치하는 항목, 즉 줄의 모든 항목 stalled:은 빈 문자열 (예 : 삭제)로 바뀝니다.
  • 마지막 p은 변환 된 선을 인쇄하는 것을 의미합니다.

일치하는 부분을 유지하려면 역 참조를 사용 \1하십시오. 교체 부분 \(…\)에서 패턴 의 그룹 내부에있는 것을 지정 합니다. 여기서 stalled:교체 부분에 다시 쓸 수 있습니다 . 이 기능은 찾고있는 패턴이 단순한 문자열보다 더 일반적인 경우에 유용합니다.

sed -n -e 's/^.*\(stalled: \)/\1/p'

때로는 경기 후 줄의 일부를 제거하고 싶을 수도 있습니다. .*$패턴의 끝에 (텍스트 .*뒤에 줄의 끝)를 포함시켜 매치에 포함시킬 수 있습니다 $. 대체 텍스트에서 참조하는 그룹에 해당 부분을 넣지 않으면 행의 끝이 출력에 포함되지 않습니다.

그룹 및 역 참조에 대한 추가 설명으로이 명령은 일치 전 부분과 일치 후 부분을 교환합니다.

sed -n -e 's/^\(.*\)\(stalled: \)\(.*\)$/\3\2\1/p'

처음 두 가지 예를 시도했지만 중단 된 것 같습니다. 오류 메시지가 표시되지 않으며 새 프롬프트가 표시되지 않습니다.
MaQleod

2
@MaQleod 오, 표준 입력에 대한 입력을 기다리고 있습니다. 리디렉션하지 않았기 때문에 여기에 터미널이 있습니다. 여기 sed … <messages에서는 파일에서 데이터를 처리하기 위해 입력 리디렉션 을 수행합니다. 다른 명령으로 생성 된 데이터를 처리하려면 파이프를 사용합니다 somecommand | sed ….
Gilles

1
맞습니다. 하루가 끝났습니다. 명령은 완벽하게 작동합니다.
MaQleod

1
내가 지금까지 본 최고의 sed 설명-감사합니다!
Jon Wadsworth

1
@ungalcrys 짧은 버전은 무엇입니까? 이것은 내 대답의 명령과 동일하지 않습니다. 나는로 작성하는 것이 좋습니다 것 sed 's/^.*stalled//'때문에 -r리눅스에 특정 및 맥 OS와 같은 다른 시스템에서 작동하지 않습니다 여기에 당신이 그것에서 어떤 혜택을받지 못하고있다.
Gilles

72

이미 사용중인 다른 표준 도구 : grep:

예를 들면 다음과 같습니다.

grep -o 'stalled.*'

Gilles의 두 번째 옵션과 동일한 결과가 있습니다.

sed -n -e 's/^.*\(stalled: \)/\1/p'

-o플래그는 반환 --only-matching물론 - - 일반적으로 그렙에 의해 수행 표현식의 일부로, 그렇지 않다 전체 라인을.

출력에서 "stalled :"를 제거하기 위해 세 번째 표준 도구 인 cut을 사용할 수 있습니다.

grep -o 'stalled.*' | cut -f2- -d:

cut명령은 분리 문자를 사용 :하고 끝까지 필드 2를 인쇄합니다. 물론 환경 설정의 문제이지만 cut기억하기 쉬운 구문입니다.


1
-o옵션 을 언급 해 주셔서 감사합니다 ! 나는 그 점을 지적하고 싶었 grep를 인식하지 못하는 \n첫 번째 예는 첫 번째로 일치하도록, 줄 바꿈으로 n문자. 예를 들어, echo "Hello Anne" | grep -o 'A[^\n]*'문자열을 반환합니다 A. 그러나 개행을 제외한 모든 문자와 일치 하므로 expect를 echo "Hello Anne" | grep -o 'A.*'반환합니다 . Anne.
adamlamar

1
cut구분 기호 주위의 따옴표 -d':'는 @poige로 제거됩니다. 나는 쉽게와 예를 따옴표로 기억 찾기 -d' '-d';'.
앤 반 로섬

당신의 발견에 따르면 따옴표도 함께 사용하는 것을 기억하는 것이 더 쉬워야합니다 -f 2. 진심으로, 왜 안돼?
poige

콜론이 ;아닌 세미콜론과 같은 구분 기호는 :따옴표로 묶지 않으면 다르게 해석 되기 때문 입니다. 물론 그것은 논리적 인 행동이지만 여전히 근육 기억에 의존하고 싶습니다. 구분 기호를 한 번 인용하고 싶지만 다른 시간은 인용하고 싶지 않습니다. 내가 전에 말한 것처럼 개인적인 선호 : 기억하기 쉽다.
Anne van Rossum

의 일부 기간 .*필요는 나를 위해 잘 작동 : cat filename | grep 'Return only this line xyz text' | grep -o 'xyz.*' 리턴xyz text
론을

4

나는 ifconfig | grep eth0 | cut -f3- -d:이것을 가지고

    [root@MyPC ~]# ifconfig
    eth0  Link encap:Ethernet  HWaddr AC:B4:CA:DD:E6:F8
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:78998810244 errors:1 dropped:0 overruns:0 frame:1
          TX packets:20113430261 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:110947036025418 (100.9 TiB)  TX bytes:15010653222322 (13.6 TiB)

그리고 이렇게 보이게

    [root@MyPC ~]# ifconfig | grep eth0 | cut -f3- -d:
    C4:7A:4D:F6:B8

2
이 질문에 대답합니까?
Stephen Rauch

1
cat /sys/class/net/*/address파싱없이을 사용할 수 있습니다 .
Anne van Rossum

1

고려한 다른 표준 도구 awk는 다음 줄과 함께 사용할 수 있습니다.

awk -F"stalled" '/stalled/{print $2}' messages

상해:

  • -F줄에 대한 구분 기호를 정의합니다 (예 : "중지됨"). 구분 기호 앞의 모든 내용 $1과로 끝나는 모든 항목을 다룹니다 $2.
  • /reg-ex/ 일치하는 정규 표현식을 검색합니다 (이 경우 "중지됨").
  • {print $<n>}-n 열을 인쇄합니다. 구분 기호가 중단 된 것으로 정의되므로 중단 된 이후의 모든 항목이 두 번째 열로 간주됩니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.