【问题标题】:Loop over indices of sliced array in bash在bash中循环切片数组的索引
【发布时间】:2019-12-29 10:29:37
【问题描述】:

我想从第二个索引开始循环遍历数组的索引。我该怎么做?

我试过了:

myarray=( "test1" "test2" "test3" "test4")
for i in ${!myarray[@]:1}
do
    # I only print the indices to simplify the example
    echo $i 
done

但不起作用。

显然这是可行的:

myarray=( "test1" "test2" "test3" "test4")
myindices=("${!myarray[@]}")
for i in ${myindices[@]:1}
do
    echo $i
done

但如果可能的话,我想在 for 循环语句中合并所有内容。

【问题讨论】:

  • 请说明数组是索引的还是关联的。
  • 它是一个索引数组。为了完整起见,我添加了更多代码。

标签: arrays bash for-loop slice


【解决方案1】:

使用# 参数长度展开:

myarray=( "test1" "test2" "test3" "test4")
for (( i=1;  i < ${#myarray[@]};  i++ ))
do
    # only print the indices to simplify the example
    echo $i 
done

请注意,! 间接扩展运算符显然与子字符串扩展不兼容,因为:

echo "${!myarray[@]:2}"

产生一个错误代码1并输出到STDERR:

bash: test1 test2 test3 test4: bad substitution

至少对于当前版本的bashv.4.4 及更早版本。不幸的是,man bash 没有充分说明 子字符串扩展 不适用于 间接扩展

【讨论】:

  • 如果有人知道 bash 愿望清单或关于使 子字符串扩展间接扩展 一起使用的功能请求错误,请发布 URL。
【解决方案2】:

我会这样做:

#!/usr/bin/env bash

myarray=('a' 'b' 'c' 'd')

start_index=2
# generate a null delimited list of indexes
printf '%s\0' "${!myarray[@]}" |
  # slice the indexes list 2nd entry to last
  cut --zero-terminated --delimiter='' --fields="${start_index}-" |
  # iterate the sliced indexes list
  while read -r -d '' i; do
    echo "$i"
  done

输出未按预期列出第一个索引0

1
2
3

也适用于关联数组:

#!/usr/bin/env bash

typeset -A myassocarray=(["foo"]='a' ["bar"]='b' ["baz"]='c' ["qux"]='d')

start_index=2
# generate a null delimited list of indexes
printf '%s\0' "${!myassocarray[@]}" |
  # slice the indexes list 2nd entry to last
  cut --zero-terminated --delimiter='' --fields="${start_index}-" |
  # iterate the sliced indexes list
  while read -r -d '' k; do
    echo "$k"
  done

输出:

bar
baz
qux

【讨论】:

  • 在我的系统 (bash v4.4.20) 上,关联代码输出:baz foo qux(但空格实际上是 \ns)。仔细观察,echo ${!myassocarray[@]} 输出:bar baz foo qux,这意味着 bash 按字母顺序排列索引名称。
  • 我认为我的意图被误解了。我想以最简单的方式在从 1 到数组最后一个索引的范围内进行 for 循环。这输出了预期的结果,但并不比我已经工作的答案简单。我只是想知道它是否可以在 for-loop 声明中以某种方式完成。
猜你喜欢
  • 2017-05-17
  • 1970-01-01
  • 2016-07-03
  • 2019-04-21
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 2021-11-12
相关资源
最近更新 更多