简体   繁体   English

如何获得特定索引处的字符串字符?

[英]How can I get a character of a string at a particular index?

I'm trying to write a script where the user enters a number as a parameter and the script calculates the sum of all the digits eg, 我正在尝试编写一个脚本,在该脚本中,用户输入数字作为参数,并且脚本计算所有数字的总和,例如,

    ./myScript 963
    18

So the script takes the string "963" and adds all the characters in the string 9+6+3=18 . 因此,脚本采用字符串“ 963”并将字符串9+6+3=18中的所有字符相加。 I'm thinking I could get the length of the string and use a loop to add all the indexes of the string together but I cannot figure out how to get an index of the string without already knowing the character you're looking for. 我在想我可以获取字符串的长度,并使用循环将字符串的所有索引加在一起,但是我无法弄清楚如何在不知道您要查找的字符的情况下获取字符串的索引。

I was able to break the string up using the following command, 我可以使用以下命令分解字符串,

    echo "963" | fold -w1
    9
    6
    3

But I'm not sure if/how I could pipe | 但是我不确定是否可以/如何使用管道| or redirect > the results into a variable and add it to a total each time. 或重定向>的结果到一个变量,并将其加入总每次。

How can I get a character of a string at a particular index? 如何获得特定索引处的字符串字符?

Update: 更新:

Example 1: 范例1:

$1=59 then the operation is 5+9=14 $ 1 = 59则运算为5 + 9 = 14

Example 2: 范例2:

$1=2222 then the operation is 2+2+2+2=8 $ 1 = 2222则运算为2 + 2 + 2 + 2 = 8

All the characters in the string are added to a total sum. 字符串中的所有字符都加在一起。

The following script loops through all of the digits in the input string and adds them together: 以下脚本循环遍历输入字符串中的所有数字,并将它们加在一起:

#!/bin/bash

s="$1"

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

echo "sum of digits: $t"

The syntax ${s:i:1} extracts a substring of length 1 from position i in the string $s . 语法${s:i:1}从字符串$s中的位置i提取长度为1的子字符串。

Output: 输出:

$ ./add.sh 963
sum of digits: 18 

If you wanted to continue adding together the digits until there was only one remaining, you could do this instead: 如果您想继续将数字加在一起,直到只剩下一个,则可以这样做:

#!/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"

The outer while loop continues as long as the length of the string is greater than 1. The inner for loop adds together each digit in the string. 只要字符串的长度大于1,外部while循环就会继续。内部for循环会将字符串中的每个数字加在一起。

Output: 输出:

$ ./add.sh 963
iteration 1: 18
iteration 2: 9
final result: 9 

Not that you asked for it but there are many ways to sum all of the digits in a string. 不是您要求的,而是有很多方法可以将字符串中的所有数字相加。 Here's another one using Perl: 这是使用Perl的另一个:

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

List::Util is a core module in Perl. List :: Util是Perl中的核心模块。 The sum subroutine does a reduction sum on a list to produce a single value. sum子例程对列表进行归约和以生成单个值。 -a enables auto-split mode so the input is split into the array @F . -a启用自动拆分模式,因此将输入拆分为数组@F -F is used to set the field delimiter (in this case it is blank, so every character counts as a separate field). -F用于设置字段定界符(在这种情况下为空白,因此每个字符都算作一个单独的字段)。 -n processes every line of input one at a time and -E is used to enter a Perl one-liner but with newer features (such as say ) enabled. -n一次处理输入的每一行,并且-E用于输入Perl单行代码,但启用了新功能(例如say )。 say is like print but a newline is added to the output. say就像print但换行符添加到输出中。

If you're not familiar with the <<< syntax, it is equivalent to echo 639 | perl ... 如果您不熟悉<<<语法,则等效于echo 639 | perl ... echo 639 | perl ... . echo 639 | perl ...

Not using string subscription but computing the desired sum: 不使用字符串订阅,而是计算所需的总和:

number=963
sum=0
for d in `echo "$number" | sed 's,\(.\), \1,g'`
do
    sum=$(($sum + $d))
done
echo $sum

Output: 18 输出:18

I would do this: 我会这样做:

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

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

both prints 都印

18

Explanation 说明

  • the grep -o . grep -o . return each digit from your number as well as the fold -w1 返回您电话号码中的每个数字以及fold -w1fold -w1
  • the paste -sd+ - merges the lines to one line using the delimiter + - eg create an calculation string like 9+6+3 paste -sd+ -使用定界符将线合并为一行+ -例如,创建一个计算字符串,如9+6+3
  • the bc does the calculation bc进行计算

if you want script, eg digadd.sh use 如果您想要脚本,例如digadd.sh使用

grep -o . <<<"$1" | paste -sd+ - | bc

using it 使用它

$ bash digadd.sh             #nothing
$ #will return nothing

$ bash digadd.sh 1273617617273450359345873647586378242349239471289638982
268
$

For fun, doing this in loop until the result is only 1 digit 为了好玩,循环执行此操作直到结果只有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"

prints 版画

sum of digits for 12938932923849028940802934092840924 is:159
sum of digits for 159 is:15
sum of digits for 15 is:6
final result: 6

another fun variant, what will extract all digits from any string is: 另一个有趣的变体,将从任何字符串中提取所有数字的是:

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

so using it in the script digadd.sh like 所以在脚本digadd.sh使用它就像

bash digadd.sh 9q6w3

produces 产生

18

The answer for your question in the title: To getting the Nth character from any string you can use 标题中您问题的答案:要从任何字符串中获取第N个字符,您可以使用

echo "$string:POSITION:length"  #position from 0

eg to get the 1st digit 例如获得第一个数字

echo "${num:0:1}"

You can use cut with -c parameter to get character at any position. 您可以使用带有-c参数的cut来在任何位置获取字符。 for example: 例如:

echo "963" | cut -c1

Outputs: 9 输出:9

使用awk

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

This can be done using substring manipulation (supported by busybox ash, but not posix sh compliant) 可以使用子字符串操作完成此操作(busybox ash支持,但不兼容posix sh)

#!/bin/ash
i=0
sum=0
while [ $i -lt ${#1} ]; do
  sum=$((sum+${1:i:1}));
  i=$((i+1))
done
echo $sum

If you really must have a posix shell compliant version, you can use: 如果确实必须具有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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM