簡體   English   中英

如何獲得特定索引處的字符串字符?

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

我正在嘗試編寫一個腳本,在該腳本中,用戶輸入數字作為參數,並且腳本計算所有數字的總和,例如,

    ./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

字符串中的所有字符都加在一起。

以下腳本循環遍歷輸入字符串中的所有數字,並將它們加在一起:

#!/bin/bash

s="$1"

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

echo "sum of digits: $t"

語法${s:i:1}從字符串$s中的位置i提取長度為1的子字符串。

輸出:

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

如果您想繼續將數字加在一起,直到只剩下一個,則可以這樣做:

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

只要字符串的長度大於1,外部while循環就會繼續。內部for循環會將字符串中的每個數字加在一起。

輸出:

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

不是您要求的,而是有很多方法可以將字符串中的所有數字相加。 這是使用Perl的另一個:

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

List :: Util是Perl中的核心模塊。 sum子例程對列表進行歸約和以生成單個值。 -a啟用自動拆分模式,因此將輸入拆分為數組@F -F用於設置字段定界符(在這種情況下為空白,因此每個字符都算作一個單獨的字段)。 -n一次處理輸入的每一行,並且-E用於輸入Perl單行代碼,但啟用了新功能(例如say )。 say就像print但換行符添加到輸出中。

如果您不熟悉<<<語法,則等效於echo 639 | perl ... echo 639 | perl ...

不使用字符串訂閱,而是計算所需的總和:

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

輸出:18

我會這樣做:

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

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

都印

18

說明

  • grep -o . 返回您電話號碼中的每個數字以及fold -w1fold -w1
  • paste -sd+ -使用定界符將線合並為一行+ -例如,創建一個計算字符串,如9+6+3
  • bc進行計算

如果您想要腳本,例如digadd.sh使用

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

使用它

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

$ bash digadd.sh 1273617617273450359345873647586378242349239471289638982
268
$

為了好玩,循環執行此操作直到結果只有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

所以在腳本digadd.sh使用它就像

bash digadd.sh 9q6w3

產生

18

標題中您問題的答案:要從任何字符串中獲取第N個字符,您可以使用

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

例如獲得第一個數字

echo "${num:0:1}"

您可以使用帶有-c參數的cut來在任何位置獲取字符。 例如:

echo "963" | cut -c1

輸出:9

使用awk

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

可以使用子字符串操作完成此操作(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

如果確實必須具有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