【问题标题】:sliced arrays flatten to len=1?切片数组展平到 len=1?
【发布时间】:2021-12-29 01:39:29
【问题描述】:

我正在用 bash 处理数组。我有一个字符串数组,其中包含空格。我想要一个包含输入数组的第一个元素以外的所有元素的数组。

input=("first string" "second string" "third string")
echo ${#input[@]}
# len(input)=3
# get slice of all except for first element of input
slice=${input[@]:1}
echo ${#slice[@]}
# expect 2, but get 1
echo $slice
# second string third string
# slice should contain ("second string" "third string"), but instead is "second string third string"

对数组进行切片显然可以消除第一个元素,但结果似乎是所有剩余字符串的串联,而不是数组。有没有办法在 bash 中对数组进行切片并得到一个数组?

(抱歉,我对 bash 并不陌生,但我以前从未使用过它,而且我找不到任何文档说明为什么我的切片是扁平的)

【问题讨论】:

标签: arrays bash


【解决方案1】:

索引被重置,元素 1 现在是元素 0:

slice=("${input[@]:1}")

元素和索引被移除,第一个元素现在是索引 1,而不是索引 0:

unset input[0]

${#slice[@]}${#input[@]} 现在将比 ${#input[@]} 的先前值小 1。从slice 中的三个元素开始,"${!slice[@]}""${!input[@]}" 的值将分别为0 11 2(对于第一种或第二种方法)

如果您不引用 slice=("${input[@]:1}"),则每个数组元素都会在空白处拆分,从而创建更多元素。

【讨论】:

    【解决方案2】:

    首先,您应该always quote variable expansions非常警惕任何依赖于未引用扩展的解决方案。 ShellCheck.net 是捕获与引用相关的错误(以及许多其他问题)的绝佳工具。

    对于您的具体问题,slice=${input[@]:1} 不符合您的要求。它定义了单个标量变量slice 而不是数组,这意味着数组扩展(由[@] 表示)将首先使用当前的IFS 转换为单个字符串。这是一个演示:

    $ arr=(1 2 '3 4')
    $ IFS=,
    $ var="${arr[@]:1}"
    $ echo "$var"
    2,3 4
    

    要改为声明和填充array,请使用=() 表示法,如下所示:

    $ var=("${arr[@]:1}")
    $ printf '%s\n' "${var[@]}"
    2
    3 4
    

    【讨论】:

      猜你喜欢
      • 2020-11-10
      • 2012-11-10
      • 1970-01-01
      • 2017-05-30
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2019-08-31
      相关资源
      最近更新 更多