简体   繁体   English

使用嵌套 for 循环 bash

[英]Using nested for loop bash

I am writing bash script for first time.我是第一次编写 bash 脚本。 I have to use nested for loop .我必须使用nested for loop I have an array like this:我有一个这样的数组:

(foo,bar a,b)

There are two elements in the array and each element in array is separated by commas.数组中有两个元素,数组中的每个元素用逗号分隔。 I want each element in array to split and print each element.我希望数组中的每个元素都拆分并打印每个元素。 The final result I want is我想要的最终结果是

foo
bar
a
b

I am using nested for loop as below but I am not getting any response我正在使用嵌套的 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]}"
    
    }
    }

You could:你可以:

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

or like:或喜欢:

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

or just:要不就:

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

or even:甚至:

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

but that said:但那说:

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

will also print the same.也会打印相同的。

Do not use { } as loop terminators - it's undocumented very old bash/shell syntax.不要使用{ }作为循环终止符 - 它是未记录的非常古老的 bash/shell 语法。 Use do..done .使用do..done

classes=... is a normal variable, not an array, and in such assignment IFS does not matter - here the right part of = is not word splitted. classes=...是一个普通变量,而不是一个数组,并且在这样的赋值中IFS无关紧要 - 这里=的右侧部分不是单词拆分。 To assign an array, use braces classes=(${classNames[n]}) .要分配数组,请使用大括号classes=(${classNames[n]})

You could just split the values on spaces and comma with IFS:您可以使用 IFS 拆分空格和逗号上的值:

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

or even like:甚至喜欢:

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

... or like this ...或像这样

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

with readread

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

The trick is that we switch ',' to ' '(space) via this bash syntax ${item//,/ } (${var_name//pattern/replacement}) this is called variable substitution.诀窍是我们通过这个 bash 语法${item//,/ } (${var_name//pattern/replacement}) 将 ',' 切换到 ' '(空格),这称为变量替换。 And this one <<< is used to read directly from var.而这个<<<是用来直接从var中读取的。

A practical one-liner solution without using an apparent loop is不使用明显循环的实用单线解决方案是

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

It runs in a subshell not to mess up with current shell's IFS .它在子shell 中运行,以免弄乱当前shell 的IFS

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM