관련된 질문이 여러 개 있는데 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"}'
(레코드당 한 줄로 공백으로 구분된 항목을 반환하도록 일부 형식을 추가했습니다.)