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

実際には、数字(次の例では自然数とゼロ)のみを抽出したい場合は、フィールド区切り記号として他のものを定義できます。

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

(レコードごとに1行のスペースで区切られたアイテムを返すようにいくつかの形式を追加しました。)

関連情報