我有这样的粘贴命令
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
也许有一个好的解决方案?
有一个名为 的 GNU 实用程序
numfmt
,它是 GNU coreutils 工具集合的一部分,看起来在这里很有用。它允许您格式化数值,以下命令将使用file2.csv
格式printf
字符串%.3f
(“精度为三位小数的浮点值”)格式化所有值。格式化值将打印在标准输出上:如您所见,默认情况下它使用“从零开始”舍入,但这可以通过例如更改
--round=nearest
:paste
您可以使用这样的进程替换将其放入您的命令中:如果您的文件是一个不“简单”的 CSV 文件,即它可能包含带引号的字段,那么您可能需要使用 CSV 感知工具,例如 Miller ( ) 来处理数据
mlr
。下面使用 Miller 在表达式中使用函数重新创建numfmt
上面的第二个示例(此函数采用格式字符串):fmtnum()
put
printf
和选项使 Miller 将输入(并写入输出)读取为无标头 CSV
--csv
。-N
你很接近;你只需要告诉
printf
小数点右边的零填充:格式字符串的
%.3f
意思是“一个浮点数,小数点右边最多三位小数”。格式字符串
%.03f
表示“小数点右侧精确三位小数的浮点数”。您可以使用它
awk
来完成所有的读取、格式化和粘贴操作:您将获得与输出中一样多的行
file1.csv
(0.000
如果行数较少,则为 file2 或 file3 为空字符串)。请注意,当环境中存在变量时
awk
,包括 GNU在内的某些实现会尊重语言环境的输入和输出十进制基数字符。例如,在十进制基数字符而不是 的法语或德语语言环境中,将被解释为不会被识别并被视为垃圾,并且您将获得输出,从而破坏 CSV 格式。awk
POSIXLY_CORRECT
,
.
1.2e5
1
.2e5
1,000
因此,
LC_ALL=C
上面将区域设置固定为C
十进制基数字符所在的位置.
。