逆参照をサポートしていない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 よりも多くの 10 進数と一致します。[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はまだこれをサポートしていません。

関連情報