Linux 如何在特定索引处获取字符串的字符?

Linux 如何在特定索引处获取字符串的字符?,linux,string,bash,Linux,String,Bash,我试图编写一个脚本,其中用户输入一个数字作为参数,脚本计算所有数字的总和,例如 ./myScript 963 18 因此,脚本接受字符串“963”并添加字符串中的所有字符9+6+3=18。我想我可以得到字符串的长度,并使用循环将字符串的所有索引添加到一起,但我无法在不知道要查找的字符的情况下找到字符串的索引 我可以使用下面的命令来分解字符串 echo "963" | fold -w1 9 6 3 但我不确定是否/如何将|或结果重定向到一个变量中

我试图编写一个脚本,其中用户输入一个数字作为参数,脚本计算所有数字的总和,例如

    ./myScript 963
    18
因此,脚本接受字符串“963”并添加字符串中的所有字符
9+6+3=18
。我想我可以得到字符串的长度,并使用循环将字符串的所有索引添加到一起,但我无法在不知道要查找的字符的情况下找到字符串的索引

我可以使用下面的命令来分解字符串

    echo "963" | fold -w1
    9
    6
    3
但我不确定是否/如何将
|
结果重定向到一个变量中,并每次将其添加到总数中

如何在特定索引处获取字符串的字符

更新:

例1:

$1=59则操作为 5+9=14

例2:

$1=2222,则操作为 2+2+2+2=8


字符串中的所有字符都被添加到一个总和中。

不使用字符串订阅,而是计算所需的总和:

number=963
总和=0
对于'echo“$number”| sed's、\(.\)、\1、g'中的d`
做
总和=$($sum+$d))
完成
回音$sum

输出:18不使用字符串订阅,而是计算所需的总和:

number=963
总和=0
对于'echo“$number”| sed's、\(.\)、\1、g'中的d`
做
总和=$($sum+$d))
完成
回音$sum

输出:18

您可以使用带有
-c
参数的
cut
来获取任何位置的字符。例如:

echo "963" | cut -c1

输出:9

您可以使用
cut
-c
参数来获取任意位置的字符。例如:

echo "963" | cut -c1

输出:9以下脚本循环输入字符串中的所有数字并将它们相加:

#!/bin/bash

s="$1"

for ((i=0; i<${#s}; ++i)); do
    ((t+=${s:i:1}))
done

echo "sum of digits: $t"
如果要继续将数字相加,直到只剩下一个数字,可以这样做:

#!/bin/bash

s="$1"

while (( ${#s} > 1 )); do
    t=0
    for ((i=0; i<${#s}; ++i)); do
        ((t+=${s:i:1}))
    done
    echo "iteration $((++n)): $t"
    s=$t
done   
echo "final result: $s"
不是你要求的,而是有很多方法可以对字符串中的所有数字求和。下面是另一个使用Perl的示例:

$ perl -MList::Util=sum -F -anE 'say sum @F' <<<639
18

$perl-MList::Util=sum-F-anE'say sum@F'以下脚本循环遍历输入字符串中的所有数字并将它们相加:

#!/bin/bash

s="$1"

for ((i=0; i<${#s}; ++i)); do
    ((t+=${s:i:1}))
done

echo "sum of digits: $t"
如果要继续将数字相加,直到只剩下一个数字,可以这样做:

#!/bin/bash

s="$1"

while (( ${#s} > 1 )); do
    t=0
    for ((i=0; i<${#s}; ++i)); do
        ((t+=${s:i:1}))
    done
    echo "iteration $((++n)): $t"
    s=$t
done   
echo "final result: $s"
不是你要求的,而是有很多方法可以对字符串中的所有数字求和。下面是另一个使用Perl的示例:

$ perl -MList::Util=sum -F -anE 'say sum @F' <<<639
18
$perl-MList::Util=sum-F-anE'say sum@F'我会这样做:

num="963"
echo "$num" | grep -o . | paste -sd+ - | bc

#or using your fold
echo "$num" | fold -w1 | paste -sd+ - | bc
两张照片

18
解释

  • grep-o.
    返回您的号码中的每个数字以及
    折叠-w1
  • 粘贴-sd+-
    使用分隔符将行合并为一行,例如创建一个计算字符串,如
    9+6+3
  • bc
    进行计算
如果需要脚本,例如
digadd.sh
使用

grep -o . <<<"$1" | paste -sd+ - | bc
为了好玩,在循环中执行此操作,直到结果只有1位数

num=12938932923849028940802934092840924
while [[ ${#num} > 1 ]]
do
    echo -n "sum of digits for $num is:"
    num=$(echo "$num" | grep -o . | paste -sd+ - | bc)
    echo $num
done
echo "final result: $num"
印刷品

sum of digits for 12938932923849028940802934092840924 is:159
sum of digits for 159 is:15
sum of digits for 15 is:6
final result: 6
另一个有趣的变体是,从任何字符串中提取所有数字的是:

grep -oP '\d' <<<"$1" | paste -sd+ - | bc
产生

18
标题中问题的答案是:从您可以使用的任何字符串中获取第n个字符

echo "$string:POSITION:length"  #position from 0
e、 g.获取第一个数字

echo "${num:0:1}"
我会这样做:

num="963"
echo "$num" | grep -o . | paste -sd+ - | bc

#or using your fold
echo "$num" | fold -w1 | paste -sd+ - | bc
两张照片

18
解释

  • grep-o.
    返回您的号码中的每个数字以及
    折叠-w1
  • 粘贴-sd+-
    使用分隔符将行合并为一行,例如创建一个计算字符串,如
    9+6+3
  • bc
    进行计算
如果需要脚本,例如
digadd.sh
使用

grep -o . <<<"$1" | paste -sd+ - | bc
为了好玩,在循环中执行此操作,直到结果只有1位数

num=12938932923849028940802934092840924
while [[ ${#num} > 1 ]]
do
    echo -n "sum of digits for $num is:"
    num=$(echo "$num" | grep -o . | paste -sd+ - | bc)
    echo $num
done
echo "final result: $num"
印刷品

sum of digits for 12938932923849028940802934092840924 is:159
sum of digits for 159 is:15
sum of digits for 15 is:6
final result: 6
另一个有趣的变体是,从任何字符串中提取所有数字的是:

grep -oP '\d' <<<"$1" | paste -sd+ - | bc
产生

18
标题中问题的答案是:从您可以使用的任何字符串中获取第n个字符

echo "$string:POSITION:length"  #position from 0
e、 g.获取第一个数字

echo "${num:0:1}"

使用
awk

awk 'split($0,a,""){for(i in a) sum+=i}END{print sum}' <<<$1

awk'split($0,a,“”){for(i in a)sum+=i}END{print sum}'使用
awk

awk 'split($0,a,""){for(i in a) sum+=i}END{print sum}' <<<$1

awk'split($0,a,“”){for(i in a)sum+=i}END{print sum}'这可以使用子字符串操作完成(受busybox ash支持,但不符合posix sh)

如果您确实必须具有与posix shell兼容的版本,则可以使用:

#!/bin/sh
sum=0
A=$1

while [ ${#B} -lt ${#A} ];do
  B=$B?
done

while [ "$A" ]; do
  B=${B#?*}
  sum=$((sum+${A%$B}))
  A=${A#?*}
done

echo $sum

这可以使用子字符串操作(由busybox ash支持,但不符合posix sh)

如果您确实必须具有与posix shell兼容的版本,则可以使用:

#!/bin/sh
sum=0
A=$1

while [ ${#B} -lt ${#A} ];do
  B=$B?
done

while [ "$A" ]; do
  B=${B#?*}
  sum=$((sum+${A%$B}))
  A=${A#?*}
done

echo $sum

你的最终目标还不清楚。你想继续把这些数字加在一起直到剩下一个吗?我对@TomFenech感到困惑,但我想,
${parameter:offset:length}
shell变量的扩展在这里很方便。你把字符串中的所有字符加在一起得到一个总数,例如,“55”应该是“5+5=10”。当我得到字符串“55”时,我应该返回10。另一个例子是“22”将返回“4”。对不起,我试过更新帖子。如果你喜欢没有循环的短小单行解决方案,你可以试试这个
((sum=$(sed's/\([0-9]\)/\1+/g;s/+$///g')你的最终目标不清楚。你想继续把数字相加直到剩下一个吗?我对@TomFenech感到困惑,但我想
${parameter:offset:length}
shell变量的扩展在这里很方便。您可以将字符串中的所有字符相加以得到一个总数,例如,“55”将是“5+5=10”。当我得到字符串“55”时,我应该返回10。另一个例子是“22”将返回“4”。我尝试过更新帖子,对不起。如果你喜欢没有循环的短小单行解决方案,你可以试试这个
((sum=$(sed的/\([0-9]\)/\1+/g;s/+$//g'),与使用参数扩展(内置到shell)相比,效率非常低.与使用参数表达式进行此操作相比,效率非常低