【问题标题】:Using nested for loop bash使用嵌套的 for 循环 bash
【发布时间】:2021-02-10 09:58:59
【问题描述】:

我是第一次写 bash 脚本。我必须使用nested for loop。我有一个这样的数组:

(foo,bar a,b)

数组中有两个元素,数组中的每个元素用逗号分隔。我希望数组中的每个元素都拆分并打印每个元素。我想要的最终结果是

foo
bar
a
b

我正在使用嵌套的 for 循环,如下所示,但我没有得到任何响应

    IFS=','
    echo "class names is::${classNames[@]}" // prints foo,bar a,b
    for ((n=0;n<${#classNames[@]};n++)){
    
    classes=${classNames[n]}
    
    for ((i=0;n<${#classes[@]};i++)){
    
    echo "${eachClass[i]}"
    
    }
    }

【问题讨论】:

  • IFS=',' aaaand IFS 计数在哪里?
  • 那么 IFS 应该是空格还是逗号?

标签: bash shell ubuntu ubuntu-16.04


【解决方案1】:

你可以:

arr=(foo,bar a,b)
for i in "${arr[@]}"; do
   while IFS=, read -ra arr_in; do
       for j in "${arr_in[@]}"; do
           echo "$j"
       done
   done <<<"$i"
done

或喜欢:

for i in "${arr[@]}"; do
   readarray -d, -t arr_in < <(printf "%s" "$i")
   for j in "${arr_in[@]}"; do
       echo "$j"
   done
done

或者只是:

while IFS=, read -ra arr_in; do
    for j in "${arr_in[@]}"; do
       echo "$j"
    done
done < <(printf "%s\n" "${arr[@]}"

甚至:

while IFS=, read -ra arr_in; do
    printf "%s\n" "${arr_in[@]}"
done < <(printf "%s\n" "${arr[@]}"

但是说:

printf "%s\n" "${arr[@]}" | tr ',' '\n'

也会打印同样的内容。

不要使用 { } 作为循环终止符 - 它是未记录的非常古老的 bash/shell 语法。使用do..done

classes=... 是一个普通变量,而不是一个数组,在这样的赋值中IFS 无关紧要——这里= 的右边部分不是分词的。要分配数组,请使用大括号classes=(${classNames[n]})

你可以用 IFS 分割空格和逗号上的值:

IFS=', ' read -ra arr <<<"${arr[*]}"
for i in "${arr[@]}"; do
    echo "$i"
done

甚至喜欢:

while IFS= read -r i; do
    echo "$i"
done < <(IFS=', '; printf "%s\n" ${arr[*]})

【讨论】:

    【解决方案2】:

    ...或者像这样

    for item in "${arr[@]}"; {
        sub=(${item//,/ })
        echo "item1=${sub[0]}"
        echo "item2=${sub[1]}"
    }
    

    read

    for item in "${arr[@]}"; {
        read i1 i2 <<< ${item//,/ }
        echo "item1=$i1"
        echo "item2=$i2"
    }
    

    诀窍是我们通过这种 bash 语法 ${item//,/ }(${var_name//pattern/replacement}) 将 ',' 切换为 ' '(空格),这称为变量替换。而这个&lt;&lt;&lt;是用来直接从var读取的。

    【讨论】:

    • 能否解释一下 //,/ 和
    【解决方案3】:

    不使用明显循环的实用单线解决方案是

    (IFS=', '; printf '%s\n' ${classNames[*]})
    

    它在子shell 中运行,以免与当前shell 的IFS 混淆。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-10
      • 1970-01-01
      相关资源
      最近更新 更多