Loop over tuples in bash?

后端 未结 12 1420
说谎
说谎 2020-12-04 21:00

Is it possible to loop over tuples in bash?

As an example, it would be great if the following worked:

for (i,j) in ((c,3), (e,5)); do echo \"$i and $         


        
相关标签:
12条回答
  • 2020-12-04 21:05
    $ echo 'c,3;e,5;' | while IFS=',' read -d';' i j; do echo "$i and $j"; done
    c and 3
    e and 5
    
    0 讨论(0)
  • 2020-12-04 21:05

    Using printf in a process substitution:

    while read -r k v; do
        echo "Key $k has value: $v"
    done < <(printf '%s\n' 'key1 val1' 'key2 val2' 'key3 val3')
    

    Key key1 has value: val1
    Key key2 has value: val2
    Key key3 has value: val3
    

    Above requires bash. If bash is not being used then use simple pipeline:

    printf '%s\n' 'key1 val1' 'key2 val2' 'key3 val3' |
    while read -r k v; do echo "Key $k has value: $v"; done
    
    0 讨论(0)
  • 2020-12-04 21:07
    $ for i in c,3 e,5; do IFS=","; set -- $i; echo $1 and $2; done
    c and 3
    e and 5
    

    About this use of set (from man builtins):

    Any arguments remaining after option processing are treated as values for the positional parameters and are assigned, in order, to $1, $2, ... $n

    The IFS="," sets the field separator so every $i gets segmented into $1 and $2 correctly.

    Via this blog.

    Edit: more correct version, as suggested by @SLACEDIAMOND:

    $ OLDIFS=$IFS; IFS=','; for i in c,3 e,5; do set -- $i; echo $1 and $2; done; IFS=$OLDIFS
    c and 3
    e and 5
    
    0 讨论(0)
  • 2020-12-04 21:10

    In cases where my tuple definitions are more complex, I prefer to have them in a heredoc:

    while IFS=", " read -ra arr; do
      echo "${arr[0]} and ${arr[1]}"
    done <<EOM
    c, 3
    e, 5
    EOM
    

    This combines looping over lines of a heredoc with splitting the lines at some desired separating character.

    0 讨论(0)
  • 2020-12-04 21:11
    do echo $key $value
    done < file_discriptor
    

    for example:

    $ while read key value; do echo $key $value ;done <<EOF
    > c 3
    > e 5
    > EOF
    c 3
    e 5
    
    $ echo -e 'c 3\ne 5' > file
    
    $ while read key value; do echo $key $value ;done <file
    c 3
    e 5
    
    $ echo -e 'c,3\ne,5' > file
    
    $ while IFS=, read key value; do echo $key $value ;done <file
    c 3
    e 5
    
    0 讨论(0)
  • 2020-12-04 21:17

    Based on the answer given by @eduardo-ivanec without setting/resetting the IFS, one could simply do:

    for i in "c 3" "e 5"
    do
        set -- $i
        echo $1 and $2
    done
    

    The output:

    c and 3
    e and 5
    
    0 讨论(0)
提交回复
热议问题