次のような貼り付けコマンドがあります。
paste -d , file1.csv file2.csv file3.csv
file2.csv には次の数字が含まれています。
0.2
0.3339
0.111111
file2.csvの値に、次のように小数点以下の3桁を含めたいと思います。
0.200
0.334
0.111
値の場合、次のように動作します。
printf "%.3f" "0.3339"
->0.334
しかし、これはfile2.csvの複数の値に対しては機能しません。
paste -d , file1.csv <(printf %s "%.3f" "$(< file2.csv)") file3.csv
たぶん良い解決策がありますか?
答え1
numfmt
ここで役に立つGNU coreutilsツールバーの一部であるGNU UtilitiesというGNUユーティリティがあります。数値の書式を指定できます。次のコマンドは、書式文字列(「小数点の3桁までの精度を持つ浮動小数点値」)をfile2.csv
使用して、すべての値を書式設定します。フォーマットされた値は標準出力に印刷されます。printf
%.3f
$ numfmt --format=%.3f <file2.csv
0.200
0.334
0.112
ご覧のとおり、デフォルトでは「0から始まる」丸めを使用しますが、次のように変更できます--round=nearest
。
$ numfmt --format=%.3f --round=nearest <file2.csv
0.200
0.334
0.111
paste
次のように、プロセス置換を使用してコマンドに挿入できます。
paste -d , file1.csv <( numfmt --format=%.3f --round=nearest <file2.csv ) file3.csv
ファイルが「単純」でないCSVの場合、つまり引用符付きフィールドを含めることができる場合は、CSV認識ツールを使用する必要があります。ミラー(mlr
)データ処理。上記の2番目の例は、Miller式numfmt
(形式文字列を使用)の関数を使用して以下で再生成されます。fmtnum()
put
printf
$ mlr --csv -N put '$1 = fmtnum($1, "%.3f")' file2.csv
0.200
0.334
0.111
および--csv
オプションを使用すると、-N
MillerはヘッダーなしのCSVで入力を読み込み、出力を書き込むことができます。
答え2
printf
ほぼ終わりました。小数点の右側にゼロパディングを教えてください。
$ cat 736678.txt
0.2
0.3339
0.111111
$ for value in $( cat 736678.txt ); do printf "%.3f\n" "$value"; done
0.200
0.334
0.111
書式文字列は、%.3f
「この点の右側に正確に3桁の小数点を持つ浮動小数点数」を意味します。
答え3
これを使用awk
して、すべての読み取り、書式設定、および貼り付け操作を実行できます。
LC_ALL=C awk '
{
getline f2 < "file2.csv"
getline f3 < "file3.csv"
printf "%s,%.3f,%s\n", $0, f2, f3
}' file1.csv
出力から任意の数の行を取得できますfile1.csv
(0.000
ファイル2に少ない行がある場合は、ファイル3に空の文字列があります)。
いくつかの実装awk
(GNUを含む)は、変数が環境に存在するとき、入力と出力でロケールの10進基本文字を尊重します。たとえば、フランス語またはドイツ語のロケールでは、10進数の基数文字が認識されず、ガベージとして扱われると解釈され、CSV形式を破る出力が得られます。awk
POSIXLY_CORRECT
,
.
1.2e5
1
.2e5
1,000
したがって、上記は10進数の基数文字がある場所LC_ALL=C
にロケールを変更します。C
.