일치하는 패턴을 따르는 줄 부분만 반환

일치하는 패턴을 따르는 줄 부분만 반환

cat따라서 파일을 연 다음 이를 사용하여 일치하는 줄을 얻으면 현재 작업 중인 특정 로그 세트에 관한 정보만 얻을 수 있습니다. grep라인을 패턴과 일치시키는 방법이 필요하지만 라인의 일치하는 부분만 반환합니다. 게임 전후 섹션은 지속적으로 변경됩니다. 나는 일치하는 부분을 제거하기 위해 행을 필터링하는 방법을 사용했거나 일치하는 후에 부분을 반환하는 방법을 알아낼 수 없습니다. 어느 쪽이든 작동합니다 sed. awk다음은 필터링해야 하는 행의 예입니다.

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 시스템이지만 도움을 주기 위해 추가로 설치할 수는 없습니다.

답변1

일반적인 도구는 sed.

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

상해:

  • -n기본적으로 아무것도 인쇄되지 않음을 의미합니다.
  • -esed 명령이 이어집니다.
  • s패턴 교체 명령입니다.
  • 정규식은 ^.*stalled:찾고 있는 패턴과 이전 텍스트( .*모든 텍스트를 의미하고 첫 문자 ^는 일치가 줄의 시작 부분에서 시작됨을 의미함)와 일치합니다. 해당 행이 여러 번 나타나는 경우 stalled:마지막 발생 항목과 일치합니다.
  • 일치하는 항목, 즉 행까지의 모든 항목이 stalled:빈 문자열로 대체(삭제)됩니다.
  • 마지막 p방법은 변환된 행을 인쇄하는 것입니다.

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

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

때로는 경기 후에 라인의 일부를 제거하고 싶을 수도 있습니다. .*$패턴 끝( .*줄 끝 뒤의 모든 텍스트 )에 추가하여 $일치 항목에 포함 할 수 있습니다 . 대체 텍스트에서 참조된 그룹 내에 섹션을 배치하지 않으면 줄 끝이 출력에 나타나지 않습니다.

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

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

부품을 구한 후첫 번째마지막 문자열 대신 문자열이 나타나는 경우(문자열이 여러 번 나타날 수 있는 줄의 경우) 일반적인 방법은 문자열을 줄 바꿈(줄에 표시되지 않는 문자)으로 한 번 교체한 다음 제거하는 것입니다. 개행 문자 이전의 모든 것:

sed -n '
  /stalled: / {
    s//\
/
    s/.*\n//p
  }'

일부 구현에서는 첫 번째 명령을 작성하는 것이 가능 sed하지만 이는 표준/이식 가능하지는 않습니다.ss//\n/

답변2

이미 사용하고 있는 다른 표준 도구 grep::

예를 들어:

grep -o 'stalled.*'

Gilles의 두 번째 옵션과 동일한 결과:

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

물론 일반적으로 grep을 사용하여 수행되는 것처럼 이 -o플래그는 전체 행이 아닌 표현식의 일부를 반환합니다 .--only-matching

출력에서 "stalled:"를 제거하려면 세 번째 사양 도구인 cut을 사용할 수 있습니다.

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

cut명령은 구분 기호를 사용 :하고 끝까지 필드 2를 인쇄합니다. 물론 선호도의 문제이지만 cut구문이 기억하기 쉽다고 생각합니다.

답변3

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

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

상해:

  • -F이 줄의 구분 기호 문자인 "스톨"을 정의합니다. 구분 기호 앞의 모든 내용은 주소 지정에 사용되고 $1구분 기호 뒤의 모든 내용은 주소 지정에 사용됩니다 $2.
  • /reg-ex/일치하는 정규식을 검색합니다. 이 경우에는 "중지되었습니다".
  • {print $<n>}- n개의 열을 인쇄합니다. 구분 기호는 중지로 정의되므로 중지 이후의 모든 항목은 두 번째 열로 간주됩니다.

답변4

Perl(일명 Perl5) 및 Raku(이전 Perl6) 사용:

진주:

perl -pe 's/^.*stalled: //; #leaves non-matching and/or blank lines intact

또는:

perl -nE '/^.*stalled: (.*)/ and say $1;'  #removes non-matching lines

행복하다:

raku -pe 's/^.*stalled\:\s//;' #leaves non-matching and/or blank lines intact

또는:

raku -ne '/^.*stalled\:\s (.*)/ and say ~$0;' #removes non-matching lines

산출(위의 두 번째 Perl 및 두 번째 Raku 예의 경우):

12:6,31, 20:1 }

위의 코드는 두 언어 간에 사실상 동일합니다. 가장 중요한 차이점은 Raku에서 Raku 정규 표현식 엔진이 "문자 그대로 이해"하려면 숫자가 아닌/밑줄이 아닌 모든 문자를 이스케이프해야 한다는 것입니다.

다른 뉘앙스는 다음과 같습니다.

  1. Raku는 캡처 번호를 $0에서 시작하도록 변경합니다(Perl은 $1에서 시작).
  2. Raku에서는 선행 ~물결표를 사용하여 일치 개체를 문자열화합니다.
  3. Perl에서는 -E명령줄 플래그를 사용하여 이 say기능을 활성화해야 합니다.

http://www.wall.org/~larry/natural.html
https://www.perl.org/
https://www.raku.org/

관련 정보