【问题标题】:Find the sum of a string of numbers in Bash scripting?在 Bash 脚本中查找一串数字的总和?
【发布时间】:2018-10-30 12:43:42
【问题描述】:

到目前为止,我有这个脚本:

#!/bin/sh
echo type in some numbers:
read input

从这里开始,我被困住了。假设input=30790148。我想要做的是将所有这些整数相加得到 3+0+7+9+0+1+4+8=32。我怎样才能做到这一点?

【问题讨论】:

标签: linux bash


【解决方案1】:

另一种不使用外部工具的方法:

read -p "Type some number: " num
for((i=0;i<${#num};i++)); do ((sum+=${num:i:1})); done

echo "$sum"

【讨论】:

  • 它在做什么:${num:i:1}。看起来像一个数字拆分器,通过在每个固定位置上加一个来将一位小数 -1- 向右移动 i
  • @Timo 是子字符串的语法。这意味着“返回从第 i 个字符开始的 1 个字符”。由于$num 是一个“字符串”,${num:i:1}bash 在其他语言中的num[i] 等价物。
  • 为什么不在此处使用 $i:((sum+=${num:i:1}))
  • 在算术扩展(( expr )) 中不强制使用$。来自手册:...shell variables may also be referenced by name without using the parameter expansion syntax.
  • 好的,使用 ((sum+=${num:i})) 而不使用 1 将是一个右移,将数组向右减少一个。
【解决方案2】:

有两个核心实用程序,foldpaste,您可以在此处使用它们(图示为 input=12345):

fold -w1 <<< $input | paste -sd+ - | bc
  • fold -w1 将输入行换行为 1 个字符的宽度:

    $ fold -w1 <<< $input
    1
    2
    3
    4
    5
    
  • paste -sd+ - 按顺序合并输入 (-s),即合并到一行中,带有 + 分隔符 (-d+),从标准输入读取(最后的 -;GNU @ 可选987654335@):

    $ fold -w1 <<< $input | paste -sd+ -
    1+2+3+4+5
    
  • bc 然后计算总和:

    $ fold -w1 <<< $input | paste -sd+ - | bc
    15
    

【讨论】:

    【解决方案3】:

    这个 awk 单行代码可能会对您有所帮助:

    awk '{for(i=1;i<=NF;i++)s+=$i}END{print s}' FS="" <<< yourString
    

    例如:

    kent$  awk '{for(i=1;i<=NF;i++)s+=$i}END{print s}' FS=""<<< "123456789" 
    45     
    

    【讨论】:

      【解决方案4】:

      这个使用sedbc

      echo "12345" | sed -e 's/\(.\)/\1\+0/g' | bc
      

      虽然+0 不直观

      编辑:使用@PaulHodges 回答中的&amp;,这将缩短为:

      echo "12345" | sed 's/./&+0/g' | bc
      

      【讨论】:

      • 这适用于bc,但要注意在数字前添加零;在某些地方,数字会突然被解释为八进制。
      • 是的,bc 将这里的所有内容解释为十进制,这确实是在滥用这一事实。我正在争取尽可能短的代码,例如sed 's/./&amp;+0/g' | bc
      • 我现在什么都想不出来,但想象一下一个被喂食的工具1+02+09+0。由于09 不是一个有效的八进制数,它肯定会出错。
      • 对不起,明白你的意思并删除了我的评论,哈哈
      【解决方案5】:

      使用sedbc -

      input=30790148; echo $input | sed 's/[0-9]/&+/g; s/$/0/;' | bc
      

      如果您没有 GNU sed,您可能需要对命令进行换行而不是使用分号。

      input=30790148;
      echo $input | 
        sed '
           s/[0-9]/&+/g
            s/$/0/
        ' | bc
      

      【讨论】:

      • 嘿,我们可以合并我们的答案并进一步简化它sed 's/./&amp;+0/g' | bc。直到&amp;,谢谢。
      • c.f.您的答案中的 cmets - 在末尾分别添加 0。
      • 是的,我只是想让它尽可能短。无论如何,感谢&amp;,工具箱中的另一个工具。
      猜你喜欢
      • 2014-02-17
      • 2017-01-02
      • 2019-11-03
      • 2014-04-10
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 2013-11-30
      • 2012-06-06
      相关资源
      最近更新 更多