2

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
0

4 Answers 4

2

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
Sign up to request clarification or add additional context in comments.

5 Comments

Solution 2 cannot be easily generalized to an arbitrary separator - what if the separator contains a % symbol?
@Leon If a character in the separator has got a special meaning inside the format string itself you may prefix it with %. In this case %% is what you're looking for.
I know. My point was that using that solution requires modifying the separator so that it is processed correctly.
@Leon : good note then, such things need to be taken into account.
2

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

Comments

0

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}"

2 Comments

you don't need eval.
@KarolyHorvath eval is needed to keep the effect of the changed IFS variable local to that command
0
#!/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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.