awk 문자열에서 숫자 추출

awk 문자열에서 숫자 추출

관련된 질문이 여러 개 있는데 awk문제를 해결하는 데 사용할 수 없는 것 같습니다.

echo "blah foo123bar234blah" | egrep -o '([0-9]+)' 

반품

123
234 

하지만

echo "blah foo123bar234blah" | 
    awk '{ match($0,/([0-9]+)/,m); print m[0], m[1],m[2]}'    

123 123합계를 반환합니다.

echo "blah foo123bar234blah" | 
    awk '{ match($0,/([0-9]+).+([0-9]+)/,m); print m[0], m[1],m[2]}'    

반품 123bar234 123 4

존재하다수동, 섹션에서:일치(문자열,정규식[,배열]), 예는 다음과 같습니다

echo foooobazbarrrrr |
    gawk '{ match($0, /(fo+).+(bar*)/, arr); print arr[1], arr[2]}'

반품 foooo barrrrr.

그렇다면 awk(와 동일)를 사용하여 grep -o문자열에서 여러 숫자를 어떻게 추출 합니까?

답변1

다중 문자 RS 및 RT에 GNU awk 사용:

$ echo "blah foo123bar234blah" |
    awk -v RS='[0-9]+' '$0=RT'
123
234

awk를 사용하십시오(강력한 일반 접근 방식이 아닌 간단한 대괄호 표현식을 사용하는 것이 더 쉽기 때문에 부정하는 대신 원래 정규식을 유지하십시오).

$ echo "blah foo123bar234blah" |
    awk -v FS='\n' '{gsub(/[0-9]+/,FS"&"FS); for (i=2;i<=NF;i+=2) print $i}'
123
234

또는:

$ echo "blah foo123bar234blah" |
    awk '{ while (match($0,/[0-9]+/) ) {print substr($0,RSTART,RLENGTH); $0=substr($0,RSTART+RLENGTH)} }'
123
234

답변2

match()함수는하나의정규식 일치. match()GNU에서 정규식 일치를 사용하여 각 숫자 집합을 찾으려면 awk반복해야 합니다.

{
    str = $0
    while (match(str,"[0-9]+",a)) {
        print a[0]
        str = substr(str,RSTART+RLENGTH)
    }
}

a[0]정규식에서는 괄호를 사용하지 않기 때문에 여기 에만 관심이 있습니다 . 괄호는 필요하지 않기 때문에 표현식에 사용하지 않습니다. 알려진 수의 정수를 단일 표현식(예: 등)과 일치시키려면 ([0-9]+)[^0-9]+([0-9]+)괄호가 필요할 수 있지만 이 연습에서는 정수가 몇 개인지 실제로 알 수 없습니다.

또는 표준을 사용하십시오 awk.

{
    str = $0
    while (match(str,"[0-9]+")) {
        print substr(str,RSTART,RLENGTH)
        str = substr(str,RSTART+RLENGTH)
    }
}

이는 의 문자열에 있는 연속 숫자와 일치합니다 str. 각 일치 항목에 대해 일치하는 문자열이 인쇄되고 str더 이상 관심이 없는 부분은 를 사용하여 제거됩니다 substr().

시험:

$ echo 'blah foo123bar234blah' | gawk '{ str = $0; while (match(str,"[0-9]+",a)) { print a[0]; str = substr(str,RSTART+RLENGTH) } }'
123
234

답변3

gsub()함수를 사용 awk하여 "숫자를 포함하지 않는 하위 문자열"이 발생할 때마다 단일 공백으로 변환한 다음 해당 split()함수를 사용하여 공백에서 결과 문자열을 분할할 수 있습니다. 이는 FS기본 변수에 대한 필드 분할과 유사하게 작동하며 선행 및 후행 "null 필드"를 삭제합니다.

awk '{gsub(/[^0-9]+/," ");n=split($0,a);for (i=1;i<=n;i++) print a[i]}'

따라서 귀하의 예를 들면 다음과 같습니다.

~$ echo "blah foo123bar234blah" | awk '{gsub(/[^0-9]+/," ");n=split($0,a);for (i=1;i<=n;i++) print a[i]}'
123
234

답변4

실제로 숫자(다음 예에서는 자연수와 0)만 추출하려는 경우 필드 구분 기호로 다른 것을 정의할 수 있습니다.

awk 'BEGIN {FS="[^0-9]+"}
     {printf $1 ; for (i=2 ; i<=NF ; i++) { printf " "$i} ; printf "\n"}'

(레코드당 한 줄로 공백으로 구분된 항목을 반환하도록 일부 형식을 추가했습니다.)

관련 정보