在Bash中添加两个变量

3

I have a fileA that contains:

  0012,001650,0089

我希望得到第一列和第二列的总和,以及第三列除以60的商。使用awk,我尝试了以下命令:
  col1=`awk -F, '{print $1}' $fileA | sed 's/0*//'`
  col2=`awk -F, '{print $2}' $fileA | sed 's/0*//'`
  col3=`awk -F, '{print $3}' $fileA | sed 's/0*//'`

  sum=$((col1 + col2))
  qou=$((col3 / 60))

但是我收到了这个错误:

apn_processing.sh[226]:col1 + col2:指定的数字对于此命令无效。

你能给我另一个解决方案吗?


请勿使用过时的反引号,改用括号,例如:col1=$(awk -F, '{print $1}' $fileA | sed 's/0*//') - Jotne
4个回答

2

Shell 是用于顺序调用工具的,仅此而已。如果您只是进行文本处理,则可以在 awk 中完成整个工作:

$ awk -F, '{
  sum = $1 + $2
  quo = $3 / 60
  print sum, quo
}' "$fileA"
1662 1.48333

如果我只需要输出整数(四舍五入),怎么办? - starpark
1
@新手:然后你可以使用awk的printf函数和适当的格式;printf "%d %d\n", sum, quo将截断小数部分。 - mklement0

2

您不需要调用awk 3次来提取字段:

$ IFS=, read -r a b c < file
$ echo $a
0012
$ echo $b
001650
$ echo $c
0089
$ echo $((10#$a + 10#$b))
1662
$ echo $((10#$c / 60))
1
$ bc  <<< "scale=3; $c/60"
1.483

在 bash 数学运算中,通过使用记号 base#number 可以指定数字的进制,这样你就不会被类似于 "0089" 这样无效的八进制数所困扰。

1

特别是当您处理浮点数算术时,我建议在awk中执行计算:

sum=$(awk -F, '{print $1+$2}' file)
qou=$(awk -F, '{print $3/60}' file)

1
假设您有理由想要将答案存储到shell变量中:
$ read sum quo < <(awk -F, '{print ($1+$2), $3/60}' "$fileA")
$ echo $sum $quo
1662 1.48333

bash 不同,awk 对输入的数字前导零没有问题。例如,观察以下示例,可以正常工作:
$ echo 016 08 | awk '{print $1, $2, $1+$2, $1/$2}'
016 08 24 2

此外

评论中的mklement0指出,如果GNU awk中的数字以零开头且为程序常量而非输入时,它将尝试将其解释为八进制数,否则将退回到十进制数。请考虑以下示例:

$ awk 'BEGIN{a=016;b=08; print a, b, a+b, a/b}'
14 8 22 1.75

在上述示例中,016 被视为八进制数。相比之下,08 不是合法的八进制数,因此被视为十进制数。

做得好!顺便说一下:GNU awk在脚本内有些含糊地识别八进制字面量(而不是通过输入),并退回到十进制解释;尝试 gawk 'BEGIN {print 010}'gawk 'BEGIN {print 08}' - mklement0
1
@mklement0 很有趣!我已将其添加到答案中。 - John1024

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接