역참조를 지원하지 않는 POSIX awk를 사용하여 일치하는 값을 "조각내는" 방법

역참조를 지원하지 않는 POSIX awk를 사용하여 일치하는 값을 "조각내는" 방법

입력이 주어지면 예를 들면 다음과 같습니다.

input value #001 is [342]
input value #002 is [8349]

출력이 다음과 같도록 [...] 내의 값을 어떻게 추출합니까?

342
8349

이는 역참조(예: "\1")를 지원하는 정규식의 경우 쉬워야 합니다. 그러나 ERE를 사용하는 POSIX awk는 이를 지원하지 않습니다.

예를 들어 POSIX sed는 역참조를 지원하므로 다음과 같습니다.

<input sed -E 's/^.*\[([[:digit:]]+)\].*$/\1/'

POSIX awk에서 이를 어떻게 수행합니까?

답변1

which를 사용하여 일치의 시작과 길이를 match()설정할 수 있습니다 (또한 일치하는 항목이 없으면 ; 또는 0을 반환합니다).RSTARTRLENGTHRSTART

awk 'match($0, /\[[[:digit:]]+\]/) {
       print substr($0, RSTART, RLENGTH)
     }'

또는:

awk 'match($0, /\[[[:digit:]]+\]/) {
       print substr($0, RSTART+1, RLENGTH-2)
     }'

괄호 없이 숫자만 원하는 경우.

mawk는 POSIX 문자 클래스를 지원하지 않으며 [[:digit:]]일부 시스템의 일부 로케일에서는 0123456789보다 더 많은 십진수와 일치합니다. [0123456789]가 아닌 이것들만 일치시키려면 를 [0-9]사용하십시오.

[digits]행에 여러 항목이 있는 경우 이 awk코드는 첫 번째 항목을 반환하고 변형은 마지막 항목을 반환합니다( sed탐욕 때문에)..*

답변2

다음 명령은 gsub각 줄에 입력된 마지막 필드에서 [및 문자를 모두 제거한 ]다음 필드를 인쇄합니다.

$ awk '{ gsub("[][]", "", $NF); print $NF }' file
342
8349

와 마찬가지로 sed각 줄의 마지막 공백 문자 앞의 모든 항목을 제거한 다음 [남은 항목에서 및 를 제거합니다.]

$ sed -e 's/.* //' -e 's/[][]//g' file
342
8349

또는 tr마지막 필드 뒤의 [am 문자를 제거하려면 또는 를 사용하십시오 ].awksed

$ awk '{ print $NF }' file | tr -d '[]'
342
8349
$ sed 's/.* //' file | tr -d '[]'
342
8349

또한 sed -EPOSIX는 아직 이를 지원하지 않습니다.

관련 정보