【问题标题】:Loop through array of arrays of string with spaces循环遍历带有空格的字符串数组
【发布时间】:2012-08-31 07:17:43
【问题描述】:

我正在尝试遍历包含其他数组的数组,这些数组由带空格的字符串组成。问题是我似乎无法保留字符串中的间距。如果我将 IFS 更改为 \n,则带有空格的字符串将分为多个项目,或者如果我将 IFS 保持不变,则数组的所有元素都被视为 1 个项目,这是一些示例代码:

#!/bin/sh
low1=("AA  QQ" "BB  LL")
low2=("CC" "DD")
low3=("EE" "FF")
high=(low1 low2 low3)

for high_item in ${high[@]}
do
   eval arrayz=\${$high_item[@]}
   #IFS=$'\n'
   for item in $arrayz
   do
      echo $item
   done
done

输出:

AA QQ BB 二 抄送 DD EE 法郎

如您所见,“AA QQ”和“BB LL”元素已被拆分。

如果我取消注释将IFS 设置为\n 的行,我会得到以下信息:

AA QQ BB LL 抄送 东风

现在“AA QQ”和“BB LL”连接起来了!

无论如何我可以保留这些元素,就像它们原来一样...我需要输出看起来像这样:

AAQQ BB LL 抄送 DD EE 法郎

【问题讨论】:

  • 对于low1,您将每个元素放在单独的行上。对于low2low3,所有元素都出现在一行中。这是故意的吗?

标签: linux arrays bash shell for-loop


【解决方案1】:

我认为你的意思是输出应该是这样的:

AA  QQ
BB  LL
CC
DD
EE
FF

即:

${low1[0]}
${low1[1]}
${low2[0]}
${low2[1]}
${low3[0]}
${low3[1]}

这可以通过以下方式完成:

#!/bin/bash

low1=("AA  QQ" "BB  LL")
low2=("CC" "DD")
low3=("EE" "FF")
high=(low1 low2 low3)

for high_item in ${high[@]}
do
    x="${high_item}[@]" # -> "low1[@]"
    arrays=( "${!x}" )

    #IFS=$'\n'
    for item in "${arrays[@]}"
    do
        echo "$item"
    done
done

并且在 bash 脚本中始终使用 #!/bin/bash

解释:${!x} 是间接变量扩展。它计算出名称包含在$x 中的变量的值。

为了我们的需要,x 也需要有 [@] 后缀来进行数组扩展。特别注意它是x=${high_item}[@]不是 x=${high_item[@]}

而您必须在数组上下文中评估它;否则,它将无法按预期工作(如果您这样做 arrays=${!x})。

啊,最后要注意的是:IFS 在这里没有任何区别。只要您在处理带引号的数组,IFS 就不会发挥作用。

【讨论】:

    【解决方案2】:

    用间接参数扩展替换eval,你会得到我认为你想要的(虽然它与你当前给定的输出不匹配:

    for high_item in "${high[@]}"
    do
        arrayz="$high_item[@]"
        # arrayz is just a string like "low1[@]"
        for item in "${!arrayz}"
        do
            echo $item
        done
    done
    

    注意需要在内部循环中引用数组扩展来保留low1元素中的空格。

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 2019-09-07
      相关资源
      最近更新 更多