如何将数字从命令行舍入到最接近的整数?

我有一个文件看起来

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 " " }'