40,000行のファイルがあります。
head flower_all
0.992957746478873 0.00704225352112677
0.646410833917366 0.353589166082634
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.992957746478873 0.00704225352112677
0.5 0.5
有効数字3個だけ維持したいと思います。私が望む出力:
0.992 0.007
0.646 0.353
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.5 0.5
どうすればいいですか?
答え1
そしてawk
:
awk '{ printf("%.3g %.3g\n", $1, $2) }' file
データを考慮すると、これは次のようになります。
0.993 0.00704
0.646 0.354
0.993 0.00704
0.993 0.00704
0.993 0.00704
0.993 0.00704
0.993 0.00704
0.993 0.00704
0.5 0.5
0.00704には小数点以下5桁がありますが、有効数字は3つです。
正確に小数点以下の3桁が必要な場合は、代わり%.3f
に使用し%.3g
て取得してください。
0.993 0.007
0.646 0.354
0.993 0.007
0.993 0.007
0.993 0.007
0.993 0.007
0.993 0.007
0.993 0.007
0.500 0.500
上記の2つのバリエーションは、GNUを使用して可変数の列に一般化できますawk
。
awk -v CONVFMT='%.3g' '{ for (i=1; i<=NF; ++i) $i+=0; print }' file
ループは各フィールドの値を$i+=0
浮動awk
小数点に再フォーマットし、それを考慮しますCONVFMT
(同等の操作を実行します$i=sprintf(CONVFMT, $i)
)。
欲しいなら切る数字:
awk '{ for (i=1; i<=NF; ++i) $i=sprintf("%.5s", $i); print }' file
これは数字を文字列として扱い、5文字以降から切り捨てます(すべての数字が10未満、0より大きいと仮定)。
0.992 0.007
0.646 0.353
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.992 0.007
0.5 0.5
より一般的な数字の切り捨ての場合:
awk '{ for (i=1; i<=NF; ++i) if (match($i,".*\\.[0-9]?[0-9]?[0-9]?")) $i=substr($i,RSTART,RLENGTH); print }' file
ループ内のアクションは、指定された正規表現の一致(一致する場合)の末尾の数字を切り捨てます。
答え2
あなたのデータには1より大きい数字はありません。ドットの前に数字の多い値を含むようにソースファイルを拡張しました。
$ cat infile
0.992957746478873 0.00704225352112677
0.646410833917366 0.353589166082634
0.992957746478873 0.00704225352112677
0.5 0.5
16.258137489137 333444.277775666
16.233399999999 333777.277111111
印刷機能
考えられる解決策の1つは、C互換のprintf機能を使用することです(awkには1つあります)。
f形式(小数点3桁(丸め))
小数点以下3桁まで正確(丸め):
$ awk '{ printf("%11.3f %11.3f\n", $1,$2) }' infile
0.993 0.007
0.646 0.354
0.993 0.007
0.500 0.500
16.258 333444.278
16.233 333777.277
0.992957746478873
に丸められているので、参考にしてください0.993
。
g形式(有効(丸め))
3桁(有効)数字の正確な数:
$ awk '{ printf("%9.3g %9.3g\n", $1,$2) }' infile
0.993 0.00704
0.646 0.354
0.993 0.00704
0.5 0.5
16.3 3.33e+05
16.2 3.34e+05
4番目の数字の丸めに注意してください(例:3.34e + 05)。
文字列(丸められていない)
小数点以下3桁(丸めなし)です。
GNU awkを使う:
$ gawk '{for(i=1;i<=NF;i++){
printf( "%12s ",gensub(/([0-9]+\.[0-9]{0,3}).*/, "\\1", "g", $i))};print""}
' infile
0.992 0.007
0.646 0.353
0.992 0.007
0.5 0.5
16.258 333444.277
16.233 333777.277
sedを使用してください(おそらくより速いでしょう):
$ sed -E 's/([0-9]+\.[0-9]{1,3})[^ ]*/\1/g' infile
0.992 0.007
0.646 0.353
0.992 0.007
0.5 0.5
16.258 333444.277
16.233 333777.277