How can I join elements of an array in Bash?

前端 未结 30 2129
爱一瞬间的悲伤
爱一瞬间的悲伤 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:13

    If you build the array in a loop, here is a simple way:

    arr=()
    for x in $(some_cmd); do
       arr+=($x,)
    done
    arr[-1]=${arr[-1]%,}
    echo ${arr[*]}
    
    0 讨论(0)
  • 2020-11-22 12:15

    Here's a 100% pure Bash function that does the job:

    join() {
        # $1 is return variable name
        # $2 is sep
        # $3... are the elements to join
        local retname=$1 sep=$2 ret=$3
        shift 3 || shift $(($#))
        printf -v "$retname" "%s" "$ret${@/#/$sep}"
    }
    

    Look:

    $ a=( one two "three three" four five )
    $ join joineda " and " "${a[@]}"
    $ echo "$joineda"
    one and two and three three and four and five
    $ join joinedb randomsep "only one element"
    $ echo "$joinedb"
    only one element
    $ join joinedc randomsep
    $ echo "$joinedc"
    
    $ a=( $' stuff with\nnewlines\n' $'and trailing newlines\n\n' )
    $ join joineda $'a sep with\nnewlines\n' "${a[@]}"
    $ echo "$joineda"
     stuff with
    newlines
    a sep with
    newlines
    and trailing newlines
    
    
    $
    

    This preserves even the trailing newlines, and doesn't need a subshell to get the result of the function. If you don't like the printf -v (why wouldn't you like it?) and passing a variable name, you can of course use a global variable for the returned string:

    join() {
        # $1 is sep
        # $2... are the elements to join
        # return is in global variable join_ret
        local sep=$1 IFS=
        join_ret=$2
        shift 2 || shift $(($#))
        join_ret+="${*/#/$sep}"
    }
    
    0 讨论(0)
  • 2020-11-22 12:15

    Shorter version of top answer:

    joinStrings() { local a=("${@:3}"); printf "%s" "$2${a[@]/#/$1}"; }
    

    Usage:

    joinStrings "$myDelimiter" "${myArray[@]}"
    
    0 讨论(0)
  • 2020-11-22 12:16

    Right now I'm using:

    TO_IGNORE=(
        E201 # Whitespace after '('
        E301 # Expected N blank lines, found M
        E303 # Too many blank lines (pep8 gets confused by comments)
    )
    ARGS="--ignore `echo ${TO_IGNORE[@]} | tr ' ' ','`"
    

    Which works, but (in the general case) will break horribly if array elements have a space in them.

    (For those interested, this is a wrapper script around pep8.py)

    0 讨论(0)
  • 2020-11-22 12:18
    $ foo=(a "b c" d)
    $ bar=$(IFS=, ; echo "${foo[*]}")
    $ echo "$bar"
    a,b c,d
    
    0 讨论(0)
  • 2020-11-22 12:18

    x=${"${arr[*]}"// /,}

    This is the shortest way to do it.

    Example,

    arr=(1 2 3 4 5)
    x=${"${arr[*]}"// /,}
    echo $x  # output: 1,2,3,4,5
    
    0 讨论(0)
提交回复
热议问题