ファイルの列を合計するプログラムがあります。
awk -v col=2 '{sum+=$col}END{print sum}' input-file
しかし、ここに問題があります。数値データがない場合、または数値が欠落しているファイルを指定した場合は、それをゼロと解釈します。
フィールドの1つを数値に解析できない場合は、エラーが発生したいと思います。
入力例は次のとおりです。
bob 1
dave 2
alice 3.5
foo bar
「bar」は数字ではないので、エラーを無視するのではなく、エラーが発生したいと思います。
ベストアンサー1
これをテストする合理的な方法は、次のようなテストを使用してフィールドを比較することです。strtod
、どちらがawkの使い方文字列を数値に変換:
$2 !~ / *[+-]?[[:digit:]]/ { print "NAN: " $2; exit 1; }
上記とstrtodの違いは、INFINITYまたはNANを「数値」と見なさないことです。 awkのデフォルトのフィールド分割動作によっては、前の空白の要件が軽減されることがあります。つまり、フィールドには先行スペースは含まれません。
$2 !~ /[+-]?[[:digit:]]/ { print "NAN: " $2; exit 1; }
Stéphaneのコメントここに答えてください:
$2 !~ /^[+-]?([[:digit:]]*\.?[[:digit:]]*([eE][-+]?[[:digit:]]+)?|0[xX][[:xdigit:]]*\.?[[:xdigit:]]*([pP][-+]?[[:digit:]]+)?)$/ { print "NAN: " $2; exit 1; }
やや良い読みやすさのために、正規表現は次のようになります。
/^[+-]?([[:digit:]]*\.?[[:digit:]]*([eE][-+]?[[:digit:]]+)?|\
0[xX][[:xdigit:]]*\.?[[:xdigit:]]*([pP][-+]?[[:digit:]]+)?)$/
...目的は、可能な前に+または-を許可し、その後に浮動小数点または16進数が続くことを許可することです。浮動小数点数には、オプションの先行数字、オプションの区切り記号(ここではピリオドで固定.
)、その後に数字、オプションで指数が続きます。 16進数は0x
またはで始まり、0X
その後に16進数、区切り記号、追加の16進数字が続き、オプションで「2乗」(指数)が続く必要があります。 2番目のフィールド全体は、次のいずれかの形式と一致する必要があります(^
およびによって固定されています$
)。この質問の目的のために、NANおよびINFINITYオプションはここで省略されています。
もう1つのオプションは、数値変換を強制し、それを0と比較し、オプションの+または-で始まる場合、元の入力を0に変換する入力とさらに比較してから0または次に続くことです。ピリオドと0:
{ number=0 + $2;
if (!number && $2 !~ /^[+-]?(0+)|\.0+/)
print "NAN: "$2;
}