Radek
Radek

Reputation: 499

bash implode array (to string)

i know in stackoverflow are some examples but they doesn't work as i need it,
example:

separator=")|("
foo=('foo bar' 'foo baz' 'bar baz')
regex="${foo[@]/#/$separator}"
regex="${regex:${#separator}}" # remove leading separator
echo "${regex}"

#output: foo bar )|(foo baz )|(bar baz

I would like to get:

#output: foo bar)|(foo baz)|(bar baz

Upvotes: 2

Views: 2102

Answers (4)

rvbarreto
rvbarreto

Reputation: 691

#!/usr/bin/env bash

joinByString() {
    local separator="$1"
    shift
    local first="$1"
    shift
    printf "%s" "$first" "${@/#/$separator}"
}

separator=")|("
foo=('foo bar' 'foo baz' 'bar baz')
output=$(joinByString "$separator" "${foo[@]}")
echo "$output"

source: https://dev.to/meleu/how-to-join-array-elements-in-a-bash-script-303a

Upvotes: 0

Radek
Radek

Reputation: 499

I need more global solution for any separator so i used loop for:

varReturn=""

implode () { 
    local separator
    separator="$1"

    #local foo
    #foo=('foo bar' 'foo baz' 'bar baz')

    local array
    array=("${!2}")

    local newString
    newString=""
    for element in "${array[@]}"
    do
        newString="$newString$separator$element"
    done
    newString="${newString:${#separator}}"
    #echo "line $LINENO: ${newString}"
    varReturn="$newString"

    return 0
}
arr=("abc cba" 2 "tree" "z%s")
sep=")%s("
implode "$sep" arr[@]
result="$varReturn"
echo "line $LINENO: $result" #line 65: abc cba)%s(2)%s(tree)%s(z%s

Upvotes: 2

Leon
Leon

Reputation: 32504

I slightly fixed your solution:

separator=")|("
foo=('foo bar' 'foo baz' 'bar baz')
IFS='' eval 'regex="${foo[*]/#/$separator}"'
regex="${regex:${#separator}}" # remove leading separator
echo "${regex}"

Upvotes: 0

sjsam
sjsam

Reputation: 21965

Hope this helps :

Solution 1

$ foo=('foo bar' 'foo baz' 'bar baz')
$ foo=( "${foo[@]/%/)|(}" ) #appending ')|('
$ i="${#foo[@]}" #Taking array count.
$ i=$(( i - 1 )) #i points to the final array element
$ foo[$i]="${foo[$i]%)|(}" # Removing ')|(' attached to the final element
$ final="${foo[*]}" # storing array as string with space separated values 
$ final="${final//\( /(}" #stripping the whitespace after '('
$ $ echo "$final" # and that is your result.
foo bar)|(foo baz)|(bar baz 

Solution 2

Okay, this would be an easier solution, i guess

$ foo=('foo bar' 'foo baz' 'bar baz')
$ final="$(printf "%s)|(" "${foo[@]}")"
$ final="${final%)|(}"
$ echo "$final"
foo bar)|(foo baz)|(bar baz

Note

printf "%s)|(" "${foo[@]}" need an explanation I guess, So here it is

  • "${foo[@]}" expands to each value in the array as separate word.
  • printf "%s)|(" is applied to each of those words above where )|( acts as a delimiter

Upvotes: 2

Related Questions