将值从道尔顿转换为千道尔顿(值除以 1000)

Rhe*_*hea 5 command-line text-processing

我们如何使用 shell 命令将道尔顿值转换为千道尔顿?我有值的列表道尔顿。一千道尔顿有 1000 道尔顿,因此需要将每个值除以一千。

样本数据:

12345.09
236575.665
18865.41
45678.87
Run Code Online (Sandbox Code Playgroud)

期望的输出:

12.34509
236.575665
18.86541
45.67887
Run Code Online (Sandbox Code Playgroud)

Eli*_*gan 15

awk

这里的任务只是将每个值除以一千。有几种很好的方法可以做到这一点——对文件中的所有值——只需一个命令。假设您的数字在一个名为的文件dalton.txt中,如您展示的示例所示,每行一个值。这是使用 AWK 的一种方法:

awk '{ print $0 / 1000.0 }' dalton.txt
Run Code Online (Sandbox Code Playgroud)

这在每一行上运行。$0在 AWK 中表示整行。正如所写的那样,输出到您的终端,但您可以将输出重定向到一个文件。这会将输出发送到kilodalton.txt(如果它已经存在则覆盖它):

awk '{ print $0 / 1000.0 }' dalton.txt > kilodalton.txt
Run Code Online (Sandbox Code Playgroud)

但是,您可能希望自定义精度。鉴于您向我们展示的示例输入,使用这些命令的终端或文件的输出是:

12.3451
236.576
18.8654
45.6789
Run Code Online (Sandbox Code Playgroud)

在您的输出示例中,每个输出值都保留与相应输入值相同的精度(就显示的信息位数而言)。如果你想要:

awk '{ printf "%.*g\n", length($0), $0 / 1000.0 }' dalton.txt
Run Code Online (Sandbox Code Playgroud)

这仍然会截断小数点后的尾随零,因为这就是printf函数g 格式说明符的行为方式。(如果你想要,你的例子并不清楚。)它的工作方式只是指定一个精度,该精度始终至少与输入中的位数一样高,但使其成为输入行的总长度, length($0).

该命令当然也可以重定向到一个文件,其输出正是您的问题中显示的输出:

12.34509
236.575665
18.86541
45.67887
Run Code Online (Sandbox Code Playgroud)

通常,您可能希望为每个条目指定相同的精度,要么是显示的数字总数,要么是小数点后显示的数字数。例如,要为每个值显示总共 6 个数字(第一行是12.3451),请使用:

awk '{ printf "%.6g\n", $0 / 1000.0 }' dalton.txt
Run Code Online (Sandbox Code Playgroud)

或者要显示每个值的小数位的3 个数字(第一行将是12.345),请使用:

awk '{ printf "%.3f\n", $0 / 1000.0 }' dalton.txt
Run Code Online (Sandbox Code Playgroud)

尽管可以在 shell 脚本中编写一个循环来读取数据,但这会更复杂,而且当一个简单的命令可以为您完成时这很少是最好的方法。即使这已经是一个更大的 shell 脚本的一部分,shell 是一种粘合语言,旨在用于调用最适合任务的任何工具。所以我建议使用这个awk方法,terdon的优秀perl方法,或者类似的。


ter*_*don 12

我只会使用perl

$ perl -lne 'print $_/1000' file
12.34509
236.575665
18.86541
45.67887
Run Code Online (Sandbox Code Playgroud)

或者awk

$ awk '{printf "%.6f\n", $1/1000}' file
12.345090
236.575665
18.865410
45.678870
Run Code Online (Sandbox Code Playgroud)


sud*_*dus 6

一般说明

假设数值存储在变量中dalton。然后它使用足够大的值来创建具有简单构造的非零值$(())

例子:

$ dalton=3800
$ echo $(($dalton/1000))
3
Run Code Online (Sandbox Code Playgroud)

正确四舍五入到最接近的整数

$ echo $(( ($dalton+500)/1000 ))
4
Run Code Online (Sandbox Code Playgroud)

如果您安装bc.

sudo apt-get install bc

$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
scale=3                        # set the number of decimals
dalton=3800
dalton/1000
3.800
(dalton+0,5)/1000
(standard_in) 4: syntax error  # use decimal point (not comma)
(dalton+0.5)/1000              # add 0.5 to get correct rounding
3.800
dalton=3800.8
(dalton+0.5)/1000
3.801
dalton=3800.2
(dalton+0.5)/1000
3.800
quit
$ 
Run Code Online (Sandbox Code Playgroud)

在 shellscript 中,您可以像这样将输入通过管道传输到 bc,

echo "scale=3
($dalton+0.5)/1000" | bc
Run Code Online (Sandbox Code Playgroud)

也可以进行交互式测试,

$ dalton=3800.8
$ echo "scale=3
($dalton+0.5)/1000" | bc
3.801
$
Run Code Online (Sandbox Code Playgroud)

脚本

使用名称创建一个shellscript converter

#!/bin/bash

dalton=

function convert2kilo {

 echo "scale=6
 ($dalton+0.0005)/1000" | bc 
}
########################################################################

# main

########################################################################

while read dalton
do
 convert2kilo
done
Run Code Online (Sandbox Code Playgroud)

和一个名称为的输入文件 input.data

12345.09
236575.665
18865.41
45678.87
1.0008
1.0002
Run Code Online (Sandbox Code Playgroud)

使 shellscript 可执行

chmod ugo+x converter
Run Code Online (Sandbox Code Playgroud)

运行 shell 脚本

$ < input.data ./converter 
12.345090
236.575665
18.865410
45.678870
.001001
.001000
$ 
Run Code Online (Sandbox Code Playgroud)