Bash 在数组上循环,打印索引和值
我想这样做:Bash 在数组上循环,打印索引和值,bash,Bash,我想这样做: foo=( ) foo[0]="bar" foo[35]="baz" for((i=0;i<${#foo[@]};i++)) do echo "$i: ${foo[$i]}" done # Output: # 0: bar # 1: 但这里我不知道索引值 我知道你可以这样做 foo=( ) foo[0]="bar" foo[35]="baz" declare -p foo # Output: # declare -a foo='([0]="bar" [35]="b
foo=( )
foo[0]="bar"
foo[35]="baz"
for((i=0;i<${#foo[@]};i++))
do
echo "$i: ${foo[$i]}"
done
# Output:
# 0: bar
# 1:
但这里我不知道索引值
我知道你可以这样做
foo=( )
foo[0]="bar"
foo[35]="baz"
declare -p foo
# Output:
# declare -a foo='([0]="bar" [35]="baz")'
但是,你不能用另一种方法吗?你会发现数组键带有
“${!foo[@]}”
(),因此:
这意味着索引将位于
$i
中,而元素本身必须通过${foo[$i]}
访问。您可以始终使用迭代参数:
ITER=0
对于${FOO[@]}中的I
做
echo${I}${ITER}
ITER=$(expr$ITER+1)
完成
在bash 4中,可以使用关联数组:
declare -A foo
foo[0]="bar"
foo[35]="baz"
for key in "${!foo[@]}"
do
echo "key: $key, value: ${foo[$key]}"
done
# output
# $ key: 0, value bar.
# $ key: 35, value baz.
在Bash3中,这是有效的(在zsh中也有效):
转储数组的简单单线技巧
我用空格添加了一个值:
foo=()
foo[12]="bar"
foo[42]="foo bar baz"
foo[35]="baz"
一、 对于快速转储数组或关联数组,我使用
此单行命令:
paste <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}")
解释
将打印由换行符分隔的所有键printf“%s\n”${!foo[@]}“
将打印所有由换行符分隔的值printf“%s\n”${foo[@]}
粘贴重要注释,虽然可以粘贴,但以空格分隔的单词列表不是数组。像这样包装它以将其转换为数组。
和双引号的使用意味着它不是一个“以空格分隔的单词列表”。您可以得到实际数组键的列表,即使单个键包含空格。@glennjackman您可以进一步解释一下吗[@]
使用[@]和双引号意味着它不是一个“以空格分隔的单词列表”
接受(数组)变量“${foo[@]}”
,并将其扩展为一个数组,保持其元素的标识,即不在空白处拆分它们。如果foo
,则foo=(x'y z')
使用两个参数调用f“${foo[@]}”
,f
和x
。元数据查询,如'y z'
和“${!foo[@]}”
类似地将“${#foo[@]}”
作为数组进行处理。答案正确,但这是难以理解的。有帮助的解释是:“foo
是数组中设置的所有索引的列表”。您的答案当然值得一点解释。请参阅。评论将有助于创建可搜索的内容。虽然此代码片段可能会解决此问题,但确实有助于提高您文章的质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。还请尽量不要用解释性注释挤满你的代码,这会降低代码和解释的可读性!我喜欢简洁的回答和策略。如果有人想知道这是bash,战略是什么,你只需要自己跟踪数组索引。”${!foo[@]}“
在现代bash中,为什么是后期增量?您只希望值递增,因此(++ITER))更直接地表示您希望做什么……不,不是“总是”。散列可以有“洞”,这意味着并非所有数字都是索引。在您的示例中${ITER}并不总是${I}的索引。这是错误的!内部循环是无用的,可能导致错误的结果!我对((ITER++)
newline的投票是我的问题!printf”%q\n“${var[@]}”
users=("kamal" "jamal" "rahim" "karim" "sadia") index=() t=-1 for i in ${users[@]}; do t=$(( t + 1 )) if [ $t -eq 0 ]; then for j in ${!users[@]}; do index[$j]=$j done fi echo "${index[$t]} is $i" done
declare -A foo foo[0]="bar" foo[35]="baz" for key in "${!foo[@]}" do echo "key: $key, value: ${foo[$key]}" done # output # $ key: 0, value bar. # $ key: 35, value baz.
map=( ) map+=("0:bar") map+=("35:baz") for keyvalue in "${map[@]}" ; do key=${keyvalue%%:*} value=${keyvalue#*:} echo "key: $key, value $value." done
foo=() foo[12]="bar" foo[42]="foo bar baz" foo[35]="baz"
paste <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}")
12 bar 35 baz 42 foo bar baz
paste -d : <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}") 12:bar 35:baz 42:foo bar baz
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "'%s'\n" "${foo[@]}") foo[12]='bar' foo[35]='baz' foo[42]='foo bar baz'
declare -A bar=([foo]=snoopy [bar]=nice [baz]=cool [foo bar]='Hello world!') paste -d = <(printf "bar[%s]\n" "${!bar[@]}") <(printf '"%s"\n' "${bar[@]}") bar[foo bar]="Hello world!" bar[foo]="snoopy" bar[bar]="nice" bar[baz]="cool"
foo[17]=$'There is one\nnewline'
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "'%s'\n" "${foo[@]}") foo[12]='bar' foo[17]='There is one foo[35]=newline' foo[42]='baz' ='foo bar baz'
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "%q\n" "${foo[@]}")
foo[12]=bar foo[17]=$'There is one\nnewline' foo[35]=baz foo[42]=foo\ bar\ baz
%q causes printf to output the corresponding argument in a format that can be reused as shell input.