循环分割字符串

时间:2020-07-15 14:57:26

标签: bash

我在bash中有一个数组声明如下:

declare -a StringArray=("A:100" "B:200" "C:300" "D:400 )

我正在尝试遍历并能够打印出以下格式:

Letter - A
Value - 100
Letter - B
Value - 200

我尝试了以下代码,但它只是像这样打印出整个字符串:

Letter - A:100
Value
Letter - B:200
export IFS=':'

for val in "${StringArray[@]}"; do
  echo "Letter - ${val[0]}"
  echo "Value - ${val[1]}"
done

5 个答案:

答案 0 :(得分:4)

删除IFS字符串拆分和关联数组创建:

#!/usr/bin/env bash

declare -a StringArray=("A:100" "B:200" "C:300" "D:400" )

IFS=:
printf 'Letter - %s\nValue - %s\n' ${StringArray[@]}

declare -A StringAssoc="($(printf '[%q]=%q ' ${StringArray[@]}))"

typeset -p StringAssoc

for k in "${!StringAssoc[@]}"; do
  printf 'Letter - %s\nValue - %s\n' "$k" "${StringAssoc[$k]}"
done

输出:

Letter - A
Value - 100
Letter - B
Value - 200
Letter - C
Value - 300
Letter - D
Value - 400
declare -A StringAssoc=([D]="400" [C]="300" [B]="200" [A]="100" )
Letter - D
Value - 400
Letter - C
Value - 300
Letter - B
Value - 200
Letter - A
Value - 100

请注意,迭代关联数组时,不会保留条目的顺序。

答案 1 :(得分:2)

您需要填充数组才能将其与索引一起使用。

#!/bin/bash
declare -a StringArray=("A:100" "B:200" "C:300" "D:400" )

IFS=:
for tuple in "${StringArray[@]}"; do
    values=($tuple)
    echo "Letter - ${values[0]}"
    echo "Value - ${values[1]}"
done

答案 2 :(得分:2)

阅读元素后,您可以使用read

for a in "${StringArray[@]}"; do
    IFS=: read v1 v2 _ <<< "$a" &&
    printf "Letter - %s\nValue - %s\n" "$v1" "$v2"
done
Letter - A
Value - 100
Letter - B
Value - 200
Letter - C
Value - 300
Letter - D
Value - 400

答案 3 :(得分:0)

单线

printf "Letter - %s\nValue - %s\n" ${StringArray[*]//:/ }
如果指定数组元素不包含空格字符,则

就足够了。在这种情况下无需循环。

否则,将需要循环:

StringArray=("A:100" "B:200" "C:300" "D:400" "E:a b")
for val in "${StringArray[@]}"; do
    IFS=: read -r name value <<< "$val"
    printf "Letter - %s\nValue - %s\n" "$name" "$value"
done

更新:在看到LéaGris的回答后,对于这种情况,似乎也不需要循环。一个简单的

(IFS=:; printf 'Letter - %s\nValue - %s\n' ${StringArray[@]})

应始终适用于所有情况,只要:始终用作分隔符即可。我宁愿在子shell中运行它,以免弄乱当前shell的IFS

答案 4 :(得分:0)

#!/bin/sh

next() {
[[ -s stack ]] && main
end
}

main() {
line=$(ed -s stack < edprint+.txt)
letter=$(echo "${line}" | cut -d':' -f1)
number=$(echo "${line}" | cut -d':' -f2)
echo "Letter = ${letter}.  Number = ${number}" >> report+.txt
ed -s stack < edpop+.txt
next
}

end() {
rm -v ./stack
rm -v ./edprint+.txt
rm -v ./edpop+.txt
exit 0
}

echo "A:100 B:200 C:300 D:400" | tr ' ' '\n' > stack

cat >> edprint+.txt << EOF
1
q
EOF

cat >> edpop+.txt << EOF
1d
wq
EOF

next

我个人真的也不喜欢数组。但是我尽量避免告诉其他人不要使用它们,因为当其他人告诉我不要使用过去我也喜欢的方法,并且我不想成为伪君子时,这会令我很烦。 >