2016-09-03 3 views
1

я знаю, в StackOverflow некоторые примеры, но они не работают, как мне это нужно,
пример:Баш Implode массив (в строке)

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 

Я хотел бы получить:

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

ответ

1

Надеется, что это помогает:

Решение 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 

Решение 2

Хорошо, это было бы более простое решение, я думаю,

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

Примечание

printf "%s)|(" "${foo[@]}" нужны объяснения я думаю, так вот это является

  • "${foo[@]}" расширяет каждое значение в массиве как отдельное слово.
  • printf "%s)|(" применяется к каждому из этих слов выше, где )|( действует как ограничитель
+0

Также проверьте мой другой ответ на [\ [добавление префикса и суффикса к позиционным параметрам \]] (http://stackoverflow.com/a/38558776/ 1620779) – sjsam

+0

Решение 2 не может быть легко обобщено на произвольный разделитель - что, если разделитель содержит символ '%'? – Leon

+0

@Leon Если символ в разделителе имеет особое значение внутри самой строки формата, вы можете префикс его '%'. В этом случае '%%' - это то, что вы ищете. – sjsam

0

Я слегка фиксированной ваше решение:

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

вам не нужно 'eval'. –

+0

@ KarolyHorvath 'eval' необходим для сохранения влияния измененной переменной IFS' на эту команду – Leon

1

мне нужно более глобальное решение для любого сепаратора таким образом я использовал цикл для :

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 
Смежные вопросы