如何将数字从命令行舍入到最接近的整数?
我有一个文件看起来
555.92 569.472 582.389 648.078 999.702 1040.75 1386.24 1418.47 1998.26 2182.13 2384.3
我需要围绕这样的每个数字
556 569 582
理想情况下,我不需要创建一个tmp文件。 怎么做 ?
通过printf函数运行文件的内容。
$ xargs -a numbers.txt -n1 printf "%1.f " 556 569 582 648 1000 1041 1386 1418 1998 2182 2384
此外,Ubuntu有一个很好的小程序叫做numfmt
,允许将数字格式化为用户定义的标准,并且人类可读。
例如,
$ xargs -a numbers.txt -n1 numfmt --to=si --round=up | xargs echo 556 570 583 649 1.0K 1.1K 1.4K 1.5K 2.0K 2.2K 2.4K
查看man numfmt
了解更多信息。
bash
只能处理整数运算。 使用更强大的语言,例如Perl:
perl -ane 'printf "%.0f ", $_ for @F' file
-
-n
逐行读取输入 -
-a
将空格上的每一行拆分为@F
数组 -
%.0f
是小数点后小数位的流格式
另一个python解决方案(一个-liner)。 在终端中运行:
python3 -c "[print(round(float(n))) for n in open('f').read().split()]"
其中'f'
是包含浮点数的源文件,在单引号之间,例如:
python3 -c "[print(round(float(n))) for n in open('/home/jacob/Bureaublad/test').read().split()]"
输出:
556 569 582 648 1000 1041 1386 1418 1998 2182 2384
另一种输出方式
如果您想要一行中的数字:
python3 -c "[print(round(float(n)), end=' ') for n in open('f').read().split()]"
(谢谢@Oli!)
输出:
556 569 582 648 1000 1041 1386 1418 1998 2182 2384
说明
命令:
python3 -c "[print(round(float(n))) for n in open('f').read().split()]"
分段:
open('f').read().split()
读取文件'f'
,将其拆分为浮点数(现在仍为字符串)
round(float(n))
首先将字符串 n
解释为float,将其舍入为整数
[print(round(float(n))) for n in open('f').read().split()]
最后,生成print命令,打印所有圆形浮点数。
使用python
:
#!/usr/bin/env python2 with open('/path/to/file.txt') as f: for line in f: numbers = line.strip().split(' ') for num in numbers: print int(round(float(num))),
-
列表
numbers
将包含空格上的所有数字(line.rstrip().split(' ')
) -
然后我们使用
round()
函数来舍入浮点数 -
由于输入存储为srings,我们需要使用
float()
函数将它们转换为浮点数 -
int()
函数将打印丢弃小数点的数字,即只打包整数部分
输出:
556 569 582 648 1000 1041 1386 1418 1998 2182 2384
awk
版本在哪里? printf
也可以在awk
:
awk '{for(i=1;i<=NF;i++) {printf "%0.f ",$i} printf "\n"}'
或没有临时文件的地方(Thx @muru )
awk -i inplace '{for(i=1;i<=NF;i++) {printf "%0.f ",$i} printf "\n"}'
例
% cat foo 555.92 569.472 582.389 648.078 999.702 1040.75 1386.24 1418.47 1998.26 2182.13 2384.3 % awk '{ for(i=1;i<=NF;i++) { printf "%0.f ",$i } printf "%s","\n" }' foo 556 569 582 648 1000 1041 1386 1418 1998 2182 2384
使用perl
:
perl -ne 'printf("%.0f ", $_) for split' file
这应该适合你:
perl -ne '@l=split(/\s+/,$_); foreach(@l){printf("%.0f",$_); print " "}'
你可以像使用它一样
echo "555.92 569.472 582.389" | perl -ne ' @l=split(/\s+/,$_); foreach(@l) { printf("%.0f",$_); print " " }'