명령줄에서 일치하는 해당 값을 어떻게 검색하고 인쇄할 수 있나요?

명령줄에서 일치하는 해당 값을 어떻게 검색하고 인쇄할 수 있나요?

예를 들어 다음 문자열이 있습니다.

2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]

MATCH찾기를 사용하여 값 10 을 인쇄하고 싶습니다 awk. 전통적인 방법을 사용하여 이 작업을 수행할 수 있지만 grep또는 을 cut사용하여 방법을 찾고 싶습니다 .sedawk

MATCH라인 어디든 있을 수 있습니다.

답변1

sed -n 's/.* MATCH: \([^ ]*\).*/\1/p'

" MATCH: "일치하는 각 줄에서 가장 오른쪽에 나오는 공백이 아닌 문자 시퀀스를 인쇄합니다.

-nsed기본적으로 인쇄되지 않는 패턴 공간을 지정합니다 . 대체가 성공하면 명령 p의 플래그는 패턴 공간(즉, 대체 결과)을 s인쇄 하도록 지시합니다.sed

그래서:

sed -n 's/pattern/replacement/p'

성공적인 대체 결과를 인쇄하는 일반적인 관용어입니다.

위의 내용은 입력이 유효한 텍스트라고 가정합니다. 왜냐하면 .*어떤 시퀀스와도 일치하기 때문입니다수치, 유효한 문자를 형성하지 않는 바이트 시퀀스와 일치하지 않습니다. 이는 일반적으로 텍스트가 다른 인코딩으로 처리될 때 UTF-8 로케일에서 발생합니다. 이러한 상황이 발생하면 위 줄 앞에 를 추가하면 됩니다 LC_ALL=C. 이렇게 하면 sed각 바이트가 문자로 처리되므로 잘못된 바이트 시퀀스가 ​​발생할 가능성이 없습니다. 여기서는 일치하는 문자가 모두 휴대용 문자 집합에 속하기 때문에 작동합니다.

표준에는 해당 기능에서 awk캡처 그룹(캡처 인)을 지원하지 않기 때문에 이에 상응하는 항목이 없습니다 .\(...\)\1sub()

여기서는 다음 기능을 사용해야 합니다 match().

awk 'match($0, / MATCH: [^ ]*/) {
       print substr($0, RSTART+8, RLENGTH-8)}'

또는 다음 기술을 사용하십시오.

awk -F ' MATCH: ' 'NF>1 {sub(/ .*/, "", $2); print $2}'

(생각하시는 분들은 참고하세요.맨 왼쪽일어난 " MATCH: ").

GNU에는 명령 과 유사한 기능을 awk수행 하지만 대체가 이루어졌는지 여부를 알려주지 않는다는 설계 버그가 있습니다. 여기에서 다음을 수행할 수 있습니다.gensub()seds

 gawk '(replacement = gensub(/.* MATCH: ([^ ]*).*/, "\\1", 1)) != $0 {
   print replacement}'

답변2

모든 행의 형식이 동일하다고 가정하면(또는 최소한 포함된 모든 행 MATCH:) 행의 5번째 요소처럼 보이고 MATCH:원하는 값은 6번째 요소입니다.

따라서 awk에서는 5번째 요소가 동일한지 테스트하고, MATCH:그렇다면 해당 줄의 6번째 요소를 인쇄합니다.

$ echo "2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]" |awk -e '{ if ($5 == "MATCH:") print $6 }' 
    10

편집: 가설이 MATCH:줄의 어느 위치에나 있을 수 있다는 점을 고려하면 다음과 같습니다.

  $ echo "2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]" |awk -e '{ for (x=1; x<NF; x++ ) { if ($x == "MATCH:") {x=x+1; printf("%s\n", $x); break}}}' 
10

매우 우아하지는 않을 수도 있지만 행의 모든 ​​필드를 반복하고 각 필드를 테스트해야 하며 이는 루프 for와 테스트로 if수행 됩니다. 테스트 필드가 일치하면 다음 필드가 인쇄됩니다.

방금 다음 행으로 직접 이동하고 현재 필드 반복을 계속하기 위해 중단을 추가했습니다.

여러 줄 파일의 경우:

$ cat terst 
2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]
2017-01-19:31:51 [ABCD:] 37723 - MATCH: 11 [text]
2017-01-19:31:51 [ABCD:] 37723 - [text]
2017-01-19:31:51 37723 - MATCH: 12 [text]
$ awk -e '{ for (x=1; x<NF; x++ ) { if ($x == "MATCH:") {x=x+1; printf("%s\n", $x); break}}}' terst 
10
11
12

관련 정보