How can I join elements of an array in Bash?

前端 未结 30 2150
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-22 12:05

If I have an array like this in Bash:

FOO=( a b c )

How do I join the elements with commas? For example, producing a,b,c.

相关标签:
30条回答
  • 2020-11-22 12:08

    Yet another solution:

    #!/bin/bash
    foo=('foo bar' 'foo baz' 'bar baz')
    bar=$(printf ",%s" "${foo[@]}")
    bar=${bar:1}
    
    echo $bar
    

    Edit: same but for multi-character variable length separator:

    #!/bin/bash
    separator=")|(" # e.g. constructing regex, pray it does not contain %s
    foo=('foo bar' 'foo baz' 'bar baz')
    regex="$( printf "${separator}%s" "${foo[@]}" )"
    regex="${regex:${#separator}}" # remove leading separator
    echo "${regex}"
    # Prints: foo bar)|(foo baz)|(bar baz
    
    0 讨论(0)
  • 2020-11-22 12:09

    Use perl for multicharacter separators:

    function join {
       perl -e '$s = shift @ARGV; print join($s, @ARGV);' "$@"; 
    }
    
    join ', ' a b c # a, b, c
    

    Or in one line:

    perl -le 'print join(shift, @ARGV);' ', ' 1 2 3
    1, 2, 3
    
    0 讨论(0)
  • 2020-11-22 12:09

    This approach takes care of spaces within the values, but requires a loop:

    #!/bin/bash
    
    FOO=( a b c )
    BAR=""
    
    for index in ${!FOO[*]}
    do
        BAR="$BAR,${FOO[$index]}"
    done
    echo ${BAR:1}
    
    0 讨论(0)
  • 2020-11-22 12:10

    With re-use of @doesn't matters' solution, but with a one statement by avoiding the ${:1} substition and need of an intermediary variable.

    echo $(printf "%s," "${LIST[@]}" | cut -d "," -f 1-${#LIST[@]} )
    

    printf has 'The format string is reused as often as necessary to satisfy the arguments.' in its man pages, so that the concatenations of the strings is documented. Then the trick is to use the LIST length to chop the last sperator, since cut will retain only the lenght of LIST as fields count.

    0 讨论(0)
  • 2020-11-22 12:10

    Perhaps I'm missing something obvious, since I'm a newb to the whole bash/zsh thing, but it looks to me like you don't need to use printf at all. Nor does it get really ugly to do without.

    join() {
      separator=$1
      arr=$*
      arr=${arr:2} # throw away separator and following space
      arr=${arr// /$separator}
    }
    

    At least, it has worked for me thus far without issue.

    For instance, join \| *.sh, which, let's say I'm in my ~ directory, outputs utilities.sh|play.sh|foobar.sh. Good enough for me.

    EDIT: This is basically Nil Geisweiller's answer, but generalized into a function.

    0 讨论(0)
  • 2020-11-22 12:12

    printf solution that accept separators of any length (based on @doesn't matters answer)

    #/!bin/bash
    foo=('foo bar' 'foo baz' 'bar baz')
    
    sep=',' # can be of any length
    bar=$(printf "${sep}%s" "${foo[@]}")
    bar=${bar:${#sep}}
    
    echo $bar
    
    0 讨论(0)
提交回复
热议问题