Вопрос: Как конкатенировать строковые переменные в Bash


В PHP строки объединяются следующим образом:

$foo = "Hello";
$foo .= " World";

Вот, $fooстановится «Hello World».

Как это делается в Баше?


2050


источник


Ответы:


foo="Hello"
foo="$foo World"
echo $foo
> Hello World

В общем, чтобы объединить две переменные, вы можете просто написать их один за другим:

a='hello'
b='world'
c=$a$b
echo $c
> helloworld

2778



Bash также поддерживает оператор + =, как показано в следующем расшифровке:

$ A="X Y"
$ A+="Z"
$ echo "$A"
X YZ

912



Сначала Бэш

Поскольку этот вопрос стоит конкретно для удар , моя первая часть ответа представила бы разные способы сделать это правильно:

+=: Добавить к переменной

Синтаксис +=могут использоваться по-разному:

Добавить в строку var+=...

(Поскольку я скромный, я буду использовать только две переменные fooа также aа затем повторно использовать то же самое во всем ответе. ;-)

a=2
a+=4
echo $a
24

Используя Вопрос переполнения стека синтаксис,

foo="Hello"
foo+=" World"
echo $foo
Hello World

работает отлично!

Добавить в целое число ((var+=...))

переменная aпредставляет собой строку, но также целое число

echo $a
24
((a+=12))
echo $a
36

Добавить в массив var+=(...)

наш aтакже является массивом только одного элемента.

echo ${a[@]}
36

a+=(18)

echo ${a[@]}
36 18
echo ${a[0]}
36
echo ${a[1]}
18

Обратите внимание, что между круглыми скобками имеется массив, разделенный пробелом , Если вы хотите сохранить строку, содержащую пробелы в вашем массиве, вы должны заключить их:

a+=(one word "hello world!" )
bash: !": event not found

Хм .. это не ошибка, а функция ... Чтобы предотвратить попытку bash !", ты мог:

a+=(one word "hello world"! 'hello world!' $'hello world\041')

declare -p a
declare -a a='([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="h
ello world!" [6]="hello world!")'

printf: Перестроить переменную, используя встроенная команда

printf встроенная команда дает мощный способ рисования строкового формата. Поскольку это Bash встроенная , существует опция отправки форматированной строки в переменную вместо печати на stdout:

echo ${a[@]}
36 18 one word hello world! hello world! hello world!

Там семь строки в этом массиве. Таким образом, мы могли бы построить форматированную строку, содержащую ровно семь позиционных аргументов:

printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'" "${a[@]}"
echo $a
36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'

Или мы могли бы использовать одна строка формата аргумента который будет повторяться, как и многие аргументы ...

Обратите внимание, что наши aвсе еще массив! Изменен только первый элемент!

declare -p a
declare -a a='([0]="36./.18...'\''one'\'' '\''word'\'', '\''hello world!'\''=='\
''hello world!'\''=='\''hello world!'\''" [1]="18" [2]="one" [3]="word" [4]="hel
lo world!" [5]="hello world!" [6]="hello world!")'

В bash, когда вы обращаетесь к имени переменной без указания индекса, вы всегда адресуете только первый элемент!

Поэтому для извлечения нашего семи массива полей нам нужно только переустановить 1-й элемент:

a=36
declare -p a
declare -a a='([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="he
llo world!" [6]="hello world!")'

Одна строка формата аргумента со многими аргументами передана:

printf -v a[0] '<%s>\n' "${a[@]}"
echo "$a"
<36>
<18>
<one>
<word>
<hello world!>
<hello world!>
<hello world!>

Используя Вопрос переполнения стека синтаксис:

foo="Hello"
printf -v foo "%s World" $foo
echo $foo
Hello World

Примечание: использование двойные кавычки может быть полезна для манипулирования строками, которые содержат spaces, tabulationsи / или newlines

printf -v foo "%s World" "$foo"

Shell теперь

Под POSIX shell, вы не могли бы использовать bashisms , поэтому нет встроенная printf,

В основном

Но вы могли бы просто сделать:

foo="Hello"
foo="$foo World"
echo $foo
Hello World

Отформатировано, используя раздвоенный printf

Если вы хотите использовать более сложные конструкции, вам нужно использовать вилка (новый дочерний процесс, который выполняет задание и возвращает результат через stdout):

foo="Hello"
foo=$(printf "%s World" "$foo")
echo $foo
Hello World

Исторически вы могли бы использовать обратные кавычки для получения результата вилка :

foo="Hello"
foo=`printf "%s World" "$foo"`
echo $foo
Hello World

Но это непросто для гнездование :

foo="Today is: "
foo=$(printf "%s %s" "$foo" "$(date)")
echo $foo
Today is: Sun Aug 4 11:58:23 CEST 2013

с backticks, вам нужно избежать внутренних вилок с обратные косые :

foo="Today is: "
foo=`printf "%s %s" "$foo" "\`date\`"`
echo $foo
Today is: Sun Aug 4 11:59:10 CEST 2013

796



Ты тоже можешь это сделать:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh

114



bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"

Выйдет

helloohaikthxbye

Это полезно, когда $blaohaiприводит к ошибке переменной, не найденной. Или если в ваших строках есть пробелы или другие специальные символы. "${foo}"должным образом избегает всего, что вы вкладываете в него.


99



foo="Hello "
foo="$foo World"


35



То, как я решаю проблему, - это просто

$a$b

Например,

a="Hello"
b=" World"
c=$a$b
echo "$c"

который производит

Hello World

Если вы попытаетесь объединить строку с другой строкой, например,

a="Hello"
c="$a World"

тогда echo "$c"будет производить

Hello World

с дополнительным пространством.

$aWorld

не работает, как вы можете себе представить, но

${a}World

производит

HelloWorld

29



$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop

21



Yet another approach...

> H="Hello "
> U="$H""universe."
> echo $U
Hello universe.

...and yet yet another one.

> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.

18



If you want to append something like an underscore, use escape (\)

FILEPATH=/opt/myfile

This does not work:

echo $FILEPATH_$DATEX

This works fine:

echo $FILEPATH\\_$DATEX

18



You can concatenate without the quotes. Here is an example:

$Variable1 Open
$Variable2 Systems
$Variable3 $Variable1$Variable2
$echo $Variable3

This last statement would print "OpenSystems" (without quotes).

This is an example of a Bash script:

v1=hello
v2=world
v3="$v1       $v2"
echo $v3            # Output: hello world
echo "$v3"          # Output: hello       world

13



Even if the += operator is now permitted, it has been introduced in Bash 3.1 in 2004.

Any script using this operator on older Bash versions will fail with a "command not found" error if you are lucky, or a "syntax error near unexpected token".

For those who cares about backward compatibility, stick with the older standard Bash concatenation methods, like those mentioned in the chosen answer:

foo="Hello"
foo="$foo World"
echo $foo
> Hello World

12