【问题标题】:array manipulation using indirection [duplicate]使用间接的数组操作
【发布时间】:2020-03-21 16:22:04
【问题描述】:

在使用间接${!varname} 时,我想在 BASH 中正确使用数组。

这是我的示例脚本:

#!/bin/bash
i="1 2 3"
x=CONFIG
y1=( "A and B" "B and C" )
# y1=( "\"A and B\"" "\"B and C\"" )
y2=( "ABC and D" )
y3=

echo "y1=${y1[@]}"
echo "y2=${y2[@]}"
echo "y3=${y3[@]}"
echo "==="

for z in $i
do
    t=y${z}
    tval=( ${!t} )
    r=0
    echo "There are ${#tval[@]} elements in ${t}."
    if [ ${#tval[@]} -gt 0 ]; then
        r=1
        echo "config_y${z}=\""
    fi
    for tv in "${tval[@]}"
    do
        [ -n "${tv}" ] && echo "${tv}"
    done
    if [ "x$r" == "x1" ]; then
        echo "\""
    fi
done

结果如下:

y1=A and B B and C
y2=ABC and D
y3=
===
There are 3 elements in y1.
config_y1="
A
and
B
"
There are 3 elements in y2.
config_y2="
ABC
and
D
"
There are 0 elements in y3.

我想得到的是:

y1=A and B B and C
y2=ABC and D
y3=
===
There are 2 elements in y1.
config_y1="
A and B
B and C
"
There are 1 elements in y2.
config_y2="
ABC and D
"
There are 0 elements in y3.

我也尝试过这样的运行:

#!/bin/bash
i="1 2 3"
x=CONFIG
y1=( "A and B" "B and C" )
# y1=( "\"A and B\"" "\"B and C\"" )
y2=( "ABC and D" )
y3=
for variable in ${!y@}
do
  echo "$variable"        # This is the content of $variable
  echo "${variable[@]}"   # So is this
  echo "${!variable}"     # This shows first element of the indexed array
  echo "${!variable[@]}"  # Not what I wanted
  echo "${!variable[0]} ${!variable[1]}"  # Not what I wanted
  echo "---"
done

理想情况下,${!Variable[@]} 应该做我想做的事,但事实并非如此。 另外,${!Variable} 只显示数组的第一个元素,

我可以尝试什么?

【问题讨论】:

标签: arrays linux bash


【解决方案1】:

您访问数组的语法在这里是错误的:

tval=( ${!t} )

这将评估为例如$y1 但您想要 "${y1[@]}",这是您使用该名称通过正确引用来寻址数组的方式。

不幸的是,没有直接的方法通过间接引用数组,但请参阅Indirect reference to array values in bash 了解一些解决方法。

还要注意如何

y3=()

不同于

y3=

对实际上不可变的东西使用变量也有点代码味道。

#!/bin/bash
i="1 2 3"
x=CONFIG
y1=( "A and B" "B and C" )
y2=( "ABC and D" )
# Fix y3 assignment
y3=()

echo "y1=${y1[@]}"
echo "y2=${y2[@]}"
echo "y3=${y3[@]}"
echo "==="

for z in $i
do
    # Add [@] as in Aaron's answer to the linked question
    t=y${z}[@]
    # And (always!) quote the variable interpolation
    tval=( "${!t}" )
    r=0
    echo "There are ${#tval[@]} elements in ${t}."
    if [ ${#tval[@]} -gt 0 ]; then
        r=1
        echo "config_y${z}=\""
    fi
    for tv in "${tval[@]}"
    do
        [ -n "${tv}" ] && echo "${tv}"
    done
    if [ "x$r" = "x1" ]; then
        echo "\""
    fi
done

可能还会调查 printf 以明确打印值。

【讨论】:

  • 如您所见,cmets 中的代码实际上并不能正常工作。当然,如果您愿意,可以使用另一个无偿变量,但我建议您不要对私有变量使用大写。
猜你喜欢
  • 2011-10-28
  • 2010-11-28
  • 1970-01-01
  • 2014-10-06
  • 2014-10-31
  • 2012-03-17
  • 2021-10-31
  • 2015-02-20
  • 1970-01-01
相关资源
最近更新 更多