次のような行を含むファイルがあります(残念ながら、これはただ他のソフトウェアの出力結果形式):
1 2 3 5/2 7 17/5 9 10/3 15
次の行に置き換える必要があります。
1 2 3 2.5 7 3.4 9 3.33 15
つまり、GAWKが除算を実行し、小数(ガラス数)を 5/2, 17/5 and 10/3
小数値に置き換えたいのです。2.5, 3.4 and 3.33.
複数のFS(フィールド区切り文字)を試しましたが、何も機能しません。 GAWKを使用してこれを行うための良い方法は何ですか?ありがとうございます。
slash (/)
に変えるともっと楽になりますかcolon (:)
?
私はなぜこの質問をするのですか?/
..の部分文字列であるかどうかを検索しようとしています。$i
(答えが「はい」の場合は、split()
$ iを2つの部分に分割して除算を実行します。)
フィールドが -$i
で始まるかどうかを確認するために別の場所で読み取ったので、then、thenなどを試しました。これらのどれも機能しません。それでAwkの特別なキャラクターだと思います。特殊文字の複雑さを避けるためにこれを使用しようと思いました。F
if ($i~/^F/)
if ($i~///)
if ($i~/"/"/)
if ($i~/\//) (escaping / with a \)
/
:
ベストアンサー1
フィールドを繰り返し、各フィールドを分割します/
。分割によって正確に2つの部分文字列が生成される場合は、それを使用してフィールドの新しい値を計算します。
$ awk '{ for (i=1; i<=NF; ++i) if (split($i,a,"/")==2) $i = a[1]/a[2] };1' file
1 2 3 2.5 7 3.4 9 3.33333 15
小数点以下の2桁の場合は、%.2f
フォーマット指定子を使用してくださいsprintf()
。
$ awk '{ for (i=1; i<=NF; ++i) { if (split($i,a,"/")==2) $i = sprintf("%.2f",a[1]/a[2]) } };1' file
1 2 3 2.50 7 3.40 9 3.33 15
同様に、ミラー:
$ mlr --nidx put 'for (k,v in $*) { a=splitnv(v,"/"); if (length(a)==2) { $[k]=a[1]/a[2] } }' file
1 2 3 2.500000 7 3.400000 9 3.333333 15
$ mlr --nidx put 'for (k,v in $*) { a=splitnv(v,"/"); if (length(a)==2) { $[k]=fmtnum(a[1]/a[2],"%.2f") } }' file
1 2 3 2.50 7 3.40 9 3.33 15
入力形式と出力形式を使用する場合、デフォルトのフィールド区切り文字nidx
は単一の空白文字です。これは、質問に表示された入力に17のフィールドがあり、そのうちのいくつかは空であることを意味します。これは出力にコピーされ、空白が保持されることを意味します。