就像这里一样,我有一个file.csv,其中的数字用引号引起来:
"0.2"
"0.3339"
"0.111111"
要舍入数字(小数点后 3 位),此解决方案效果很好:
printf "%.03f\n" $(sed 's/\"//g' file.csv)
但现在我想存储sed 's/\"//g' file.csv
为变量
var_sed=$(sed 's/\"//g' file.csv);
printf "%.03f\n" ${var_sed}
不起作用。输出是
zsh: bad math expression: operator expected at `0.3339\n0.1...'
0.000
所以问题是var_sed
传递\n
给printf "%.03f\n"
.
我知道的唯一解决方案是:
var_sed=$(sed 's/\"//g' file.csv);
printf "%.03f\n" $(echo ${var_sed})
- 也许有更清洁的方法。
- 我也想加入
printf "%.03f\n"
这样的函数:
printf_function () { printf "%.03f\n" $1;}
但这不起作用:
printf_function () { printf "%.03f\n" $1;};
var_sed=$(sed 's/\"//g' file.csv);
printf_function ${var_sed}
也printf_function $(echo ${var_sed})
没有工作。
______________________________________________________________
为什么我尝试将文件保存在变量中? ______________________________________________________________
事实是我实际上想把命令sed
放在一个函数中。对不起,我把它作为一个变量来(试图)简化问题。
我的脚本是
sed_01 () { sed 's/\"$// ; s/^\"// ; s/something_else//g' $1;};
printf_03 () { printf "%.03f\n" $1;};
printf_03 "$(sed_01 file.csv)"
正如下面评论中提到的,它适用于 bash。
输出:
"0.200"
"0.334"
"0.111"
但在 zsh 中输出:是:
printf_03: bad math expression: operator expected at `0.3339\n0.1...'
0.000
这依赖于分词来将数字作为
printf
单独的参数。问题是,zsh 已经放弃了自动分词作为过去愚蠢的残余,并且不会为变量扩展做这件事。但无论出于何种原因,它确实是为了命令替换而这样做的。从命令替换分配给常规标量变量时也没有拆分,因此
sed
get 输出中的换行符保存在变量中。这就是为什么您的代码适用于命令替换,但不适用于中间变量。
如果您确实需要先将值加载到变量中(而不仅仅是为了打印),请考虑将它们存储在数组中 (zsh):
在 Bash 中,你会使用
readarray
/mapfile
:或者,如果你想要的东西在任何一个中都有效,你将不得不再次依赖分词:
请注意括号,它们使数组赋值,因此再次发生分词。(“大部分”包括影响行为的修改的常见警告,并且文件名通配也发生了。)
IFS
话又说回来,这样的事情可能只用 AWK 更容易完成: