関連する質問がいくつかありますが、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行のスペースで区切られたアイテムを返すようにいくつかの形式を追加しました。)