Как объединить строковые переменные в Bash

2770

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

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

Здесь $fooстановится "Hello World".

Как это достигается в Bash?

клубника
источник
6
foo="Hello" foo=$foo" World" echo $foo это скорее сработало для "#! / bin / sh"
parasrish
1
Что делать, если вы хотите HelloWorld без пробела?
Ади
@Adifoo1="World" foo2="Hello" foo3="$foo1$foo2"
GeneCode
пробелы имеют значение в bash)
Capibar

Ответы:

3767
foo="Hello"
foo="${foo} World"
echo "${foo}"
> Hello World

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

a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
codaddict
источник
314
Вероятно, это хорошо, чтобы привыкнуть вставлять $fooдвойные кавычки, для тех случаев, когда это действительно имеет значение.
Каскабель
104
Нас учат всегда делать это, потому что, когда происходит замена, оболочки будут игнорировать пробелы, но двойные кавычки всегда будут защищать эти пробелы.
Клубника
62
Должен ли быть пробел в вашем первом примере? Можно ли сделать что-то подобное foo="$fooworld"? Я бы предположил, что нет ...
безразлично
341
@nonsensickle Это будет искать переменную с именем fooworld. foo="${foo}world"
Устранение неоднозначности,
4
@ JVE999 Да, это тоже работает, хотя, на мой взгляд, это не так хорошо для ясности кода ... Но это может быть моим предпочтением ... Есть пара других способов, которыми это можно сделать - дело в том, убедитесь, что имя переменной отделено от частей без имени переменной, чтобы она анализировалась правильно.
Твальберг
1128

Bash также поддерживает +=оператор, как показано в этом коде:

$ A="X Y"
$ A+=" Z"
$ echo "$A"
X Y Z
thkala
источник
2
Могу ли я использовать этот синтаксис с ключевым словом экспорта? например export A+="Z"или, может быть, Aпеременную нужно экспортировать только один раз?
Levesque
3
@levesque: оба :-). Переменные нужно экспортировать только один раз, но export A+=Zэто тоже очень хорошо работает.
Thkala
38
Поскольку это bashism, я думаю, стоит упомянуть, что вы никогда не должны использовать #!/bin/shв сценарии, использующем эту конструкцию.
Score_Under
2
Это конкретно и только оператор плюс-равно. То есть, в отличие от Javascript, в Bash эхо $ A + $ B печатает "X Y + Z"
phpguru
6
Башизм - это функция оболочки, которая поддерживается только в bashнекоторых и более продвинутых оболочках. Он не будет работать busybox shни с dash( или (что /bin/shна многих дистрибутивах)), ни с некоторыми другими оболочками, такими как /bin/shпредоставленные во FreeBSD.
Score_Under
961

Баш первый

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

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

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

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

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

a=2
a+=4
echo $a
24

Используя синтаксис вопроса Stack Overflow ,

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

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

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

Shell сейчас

В оболочке POSIX вы не можете использовать 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

с обратными чертами вы должны избегать внутренних вилок с обратными слешами :

foo="Today is: "
foo=`printf "%s %s" "$foo" "\`date\`"`
echo $foo
Today is: Sun Aug 4 11:59:10 CEST 2013
Ф. Хаури
источник
4
+=Оператор также намного быстрее , чем $a="$a$b"в моих тестах .. Какой смысл.
Мэтт
7
Этот ответ потрясающий, но я думаю, что он пропускает var=${var}.shпример из других ответов, что очень полезно.
Генераорама
1
Является bashединственная оболочка с +=оператором? Я хочу посмотреть, достаточно ли она портативна
dashesy
1
@dashesy нет. это, конечно, не единственная оболочка с +=оператором, но все эти способы - башмы , поэтому не переносимы! Даже вы можете столкнуться со специальной ошибкой в ​​случае неправильной версии bash!
Ф. Хаури
134

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

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh
userend
источник
4
Хотя специальные символы и пробелы не используются, двойные кавычки, кавычки и фигурные скобки бесполезны: var=myscript;var=$var.sh;echo $varбудут иметь те же эффекты (это работает в bash, dash, busybox и других).
Ф. Хаури
@ Ф.Хаури, спасибо, что указал на это. Но если вы добавите число, оно не будет работать: например echo $var2, не производитmyscript2
Pynchia
@Pynchia Эта работа из-за .недопустимой точки в имени переменной. Если еще echo ${var}2или посмотри мой ответ
Ф. Хаури
119
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"

Будет выходной

helloohaikthxbye

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

orkoden
источник
3
Не работает Я получаю «backupstorefolder: команда не найдена» из bash, где «backupstorefolder» - это имя переменной.
Зиан Чой,
7
Это помогает подсвечивать синтаксис и устраняет некоторую двусмысленность.
Рэй Фосс
44
foo="Hello "
foo="$foo World"

     

vinothkr
источник
10
Это самый полезный ответ для сценариев оболочки. Я нашел себя последние 30 минут, потому что у меня было место до и после знака равенства!
Стефан
8
foo = "$ {foo} World"
XXL
@XXL, конечно, я бы предпочел использовать скобки для инкапсуляции имени var. Настоятельно рекомендуется
Серхио А.
33

Я бы решил проблему просто

$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
Крис Смит
источник
1
... следовательно ${a}\ WorldпроизводитHello World
XavierStuvw
Это удивляет меня; Я бы ожидал c=$a$bздесь сделать то же самое, что c=$a World(который будет пытаться запускаться Worldкак команда). Я предполагаю, что это означает, что присвоение анализируется до
раскрытия
31

Вот краткое резюме того, о чем говорит большинство ответов.

Допустим, у нас есть две переменные и $ 1 установлен на «один»:

set one two
a=hello
b=world

Таблица ниже объясняет различные контексты, в которых мы можем комбинировать значения aи bсоздавать новую переменную c.

Context                               | Expression            | Result (value of c)
--------------------------------------+-----------------------+---------------------
Two variables                         | c=$a$b                | helloworld
A variable and a literal              | c=${a}_world          | hello_world
A variable and a literal              | c=$1world             | oneworld
A variable and a literal              | c=$a/world            | hello/world
A variable, a literal, with a space   | c=${a}" world"        | hello world
A more complex expression             | c="${a}_one|${b}_2"   | hello_one|world_2
Using += operator (Bash 3.1 or later) | c=$a; c+=$b           | helloworld
Append literal with +=                | c=$a; c+=" world"     | hello world

Несколько заметок:

  • Заключение RHS присвоения в двойные кавычки, как правило, является хорошей практикой, хотя во многих случаях оно является необязательным.
  • += лучше с точки зрения производительности, если большая строка строится с небольшими приращениями, особенно в цикле
  • использовать {}вокруг имен переменных, чтобы устранить неоднозначность их расширения (как в строке 2 в таблице выше). Как видно из строк 3 и 4, в этом нет необходимости, {}если переменная не конкатенируется со строкой, которая начинается с символа, который является допустимым первым символом в имени переменной оболочки, то есть является алфавитом или подчеркиванием.

Смотрите также:

codeforester
источник
2
Если вас беспокоит производительность, посмотрите анализ в моем ответе stackoverflow.com/a/47878161/117471
Бруно Броноски
29
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
bcosca
источник
20

Еще один подход ...

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

... и еще один.

> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.
Аксели Пален
источник
1
Это то, что я сделал, и я нашел это намного проще и понятнее, чем другие ответы. Есть ли причина, по которой никто в ответах с наибольшим количеством голосов не указал этот вариант?
Quimnuss
1
@quimnuss Тот факт, что строки не соответствуют тем, которые используются в вопросе OP, может быть хорошей причиной.
июля
20

Если вы хотите добавить что-то вроде подчеркивания, используйте escape (\)

FILEPATH=/opt/myfile

Это не работает:

echo $FILEPATH_$DATEX

Это прекрасно работает:

echo $FILEPATH\\_$DATEX
user2800471
источник
11
Или, альтернативно, $ {FILEPATH} _ $ DATEX. Здесь {} используются для обозначения границ имени переменной. Это приемлемо, потому что подчеркивание является допустимым символом в именах переменных, поэтому в вашем фрагменте bash фактически пытается разрешить FILEPATH_, а не только $ FILEPATH
Nik O'Lai
1
для меня у меня была одна переменная, т. е. $ var1 и константа рядом с ней, поэтому echo $ var1_costant_traling_part работает для меня
YouAreAwesome
2
Я думаю, что для побега нужна только одна обратная реакция: echo $a\_$bбудет. Как намекает в комментарии Ник О'Лай, подчеркивание является регулярным символом. Обработка пробелов намного более чувствительна к строкам, эхо и конкатенации - \ этот поток можно использовать и внимательно читать, так как эта проблема возникает время от времени.
XavierStuvw
16

Самый простой способ с кавычками:

B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
betontalpfa
источник
1
Слишком много кавычек, ИМХО. var=$B$b"a"; echo Hello\ $varсделал бы, я верю
XavierStuvw
Я предлагаю использовать все кавычки, потому что если вы поставите его везде, где вы не можете пропустить, вам не нужно думать.
Betontalpfa
15

Вы можете объединить без кавычек. Вот пример:

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

Это последнее утверждение напечатало бы "OpenSystems" (без кавычек).

Это пример скрипта Bash:

v1=hello
v2=world
v3="$v1       $v2"
echo $v3            # Output: hello world
echo "$v3"          # Output: hello       world
Мариана Софер
источник
1
Синтаксис первого блока сбивает с толку. Что означают эти знаки $?
XavierStuvw
15

Даже если теперь разрешен оператор + =, он был введен в Bash 3.1 в 2004 году.

Любой сценарий, использующий этот оператор в старых версиях Bash, завершится с ошибкой «команда не найдена», если вам повезет, или с «синтаксической ошибкой рядом с неожиданным токеном».

Для тех, кому небезразлична обратная совместимость, придерживайтесь старых стандартных методов конкатенации Bash, таких как упомянутые в выбранном ответе:

foo="Hello"
foo="$foo World"
echo $foo
> Hello World
Луи-Феликс
источник
1
Спасибо за указание на это, я просто искал, какая версия требуется, чтобы это работало.
Ро Пхи
14

Я предпочитаю использовать фигурные скобки ${}для расширения переменной в строке:

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

Вьющиеся скобки подойдут для непрерывного использования строки:

foo="Hello"
foo="${foo}World"
echo $foo
> HelloWorld

В противном случае использование foo = "$fooWorld"не будет работать.

Ник Цай
источник
8

Если вы пытаетесь разделить строку на несколько строк, вы можете использовать обратную косую черту:

$ a="hello\
> world"
$ echo $a
helloworld

С одним пробелом между:

$ a="hello \
> world"
$ echo $a
hello world

Этот также добавляет только один пробел между:

$ a="hello \
>      world"
$ echo $a
hello world
jcarballo
источник
Боюсь, это не то, что имелось в виду
installero
7

Более безопасный способ:

a="AAAAAAAAAAAA"
b="BBBBBBBBBBBB"
c="CCCCCCCCCCCC"
d="DD DD"
s="${a}${b}${c}${d}"
echo "$s"
AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD

Строки, содержащие пробелы, могут стать частью команды, используйте «$ XXX» и «$ {XXX}», чтобы избежать этих ошибок.

Плюс взгляните на другой ответ о + =

Богдана
источник
Точка строк с пробелом, которые читаются как команда, отображается в точке определения. Так d=DD DDчто дайте DD: command not found--- обратите внимание, что это последний DD, а скорее d, который не найден. Если все операнды правильно отформатированы и уже содержат необходимые пробелы, вы можете просто объединить их s=${a}${b}${c}${d}; echo $sс меньшим количеством кавычек. Также вы можете использовать \ (экранированный пробел), чтобы избежать этих проблем - d=echo\ echoне будет запускать эхо-вызов, тогда как d=echo echoбудет.
XavierStuvw
7

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

user=daniel
cat > output.file << EOF
"$user"san
EOF

Будет выводить "daniel"san, а не так danielsan, как вы, возможно, хотели. В этом случае вы должны сделать вместо этого:

user=daniel
cat > output.file << EOF
${user}san
EOF
diogovk
источник
6
a="Hello,"
a=$a" World!"
echo $a

Вот как вы объединяете две строки.

CodeNinjaPI
источник
1
Это работает, но иногда дает непредсказуемые результаты, потому что интерполяция переменных не защищена. Таким образом, вы не можете полагаться на эту форму для всех случаев использования.
Энтони Ратледж,
5

Если это как ваш пример добавления " World"к исходной строке, то это может быть:

#!/bin/bash

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

Выход:

Hello World
nonopolarity
источник
5
var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3
хари
источник
2
Также var3=$var1\ $var2имеет тот же эффект
XavierStuvw
5

Есть высказанные опасения по поводу производительности, но данные не предлагаются. Позвольте мне предложить простой тест.

(ПРИМЕЧАНИЕ: dateна macOS не предлагает наносекунд, поэтому это должно быть сделано на Linux.)

Я создал append_test.sh на GitHub с содержанием:

#!/bin/bash -e

output(){
    ptime=$ctime;
    ctime=$(date +%s.%N);
    delta=$(bc <<<"$ctime - $ptime");
    printf "%2s. %16s chars  time: %s  delta: %s\n" $n "$(bc <<<"10*(2^$n)")" $ctime $delta;
}

method1(){
    echo 'Method: a="$a$a"'
    for n in {1..32}; do a="$a$a"; output; done
}

method2(){
    echo 'Method: a+="$a"'
    for n in {1..32}; do a+="$a";  output; done
}

ctime=0; a="0123456789"; time method$1

Тест 1:

$ ./append_test.sh 1
Method: a="$a$a"
 1.               20 chars  time: 1513640431.861671143  delta: 1513640431.861671143
 2.               40 chars  time: 1513640431.865036344  delta: .003365201
 3.               80 chars  time: 1513640431.868200952  delta: .003164608
 4.              160 chars  time: 1513640431.871273553  delta: .003072601
 5.              320 chars  time: 1513640431.874358253  delta: .003084700
 6.              640 chars  time: 1513640431.877454625  delta: .003096372
 7.             1280 chars  time: 1513640431.880551786  delta: .003097161
 8.             2560 chars  time: 1513640431.883652169  delta: .003100383
 9.             5120 chars  time: 1513640431.886777451  delta: .003125282
10.            10240 chars  time: 1513640431.890066444  delta: .003288993
11.            20480 chars  time: 1513640431.893488326  delta: .003421882
12.            40960 chars  time: 1513640431.897273327  delta: .003785001
13.            81920 chars  time: 1513640431.901740563  delta: .004467236
14.           163840 chars  time: 1513640431.907592388  delta: .005851825
15.           327680 chars  time: 1513640431.916233664  delta: .008641276
16.           655360 chars  time: 1513640431.930577599  delta: .014343935
17.          1310720 chars  time: 1513640431.954343112  delta: .023765513
18.          2621440 chars  time: 1513640431.999438581  delta: .045095469
19.          5242880 chars  time: 1513640432.086792464  delta: .087353883
20.         10485760 chars  time: 1513640432.278492932  delta: .191700468
21.         20971520 chars  time: 1513640432.672274631  delta: .393781699
22.         41943040 chars  time: 1513640433.456406517  delta: .784131886
23.         83886080 chars  time: 1513640435.012385162  delta: 1.555978645
24.        167772160 chars  time: 1513640438.103865613  delta: 3.091480451
25.        335544320 chars  time: 1513640444.267009677  delta: 6.163144064
./append_test.sh: fork: Cannot allocate memory

Тест 2:

$ ./append_test.sh 2
Method: a+="$a"
 1.               20 chars  time: 1513640473.460480052  delta: 1513640473.460480052
 2.               40 chars  time: 1513640473.463738638  delta: .003258586
 3.               80 chars  time: 1513640473.466868613  delta: .003129975
 4.              160 chars  time: 1513640473.469948300  delta: .003079687
 5.              320 chars  time: 1513640473.473001255  delta: .003052955
 6.              640 chars  time: 1513640473.476086165  delta: .003084910
 7.             1280 chars  time: 1513640473.479196664  delta: .003110499
 8.             2560 chars  time: 1513640473.482355769  delta: .003159105
 9.             5120 chars  time: 1513640473.485495401  delta: .003139632
10.            10240 chars  time: 1513640473.488655040  delta: .003159639
11.            20480 chars  time: 1513640473.491946159  delta: .003291119
12.            40960 chars  time: 1513640473.495354094  delta: .003407935
13.            81920 chars  time: 1513640473.499138230  delta: .003784136
14.           163840 chars  time: 1513640473.503646917  delta: .004508687
15.           327680 chars  time: 1513640473.509647651  delta: .006000734
16.           655360 chars  time: 1513640473.518517787  delta: .008870136
17.          1310720 chars  time: 1513640473.533228130  delta: .014710343
18.          2621440 chars  time: 1513640473.560111613  delta: .026883483
19.          5242880 chars  time: 1513640473.606959569  delta: .046847956
20.         10485760 chars  time: 1513640473.699051712  delta: .092092143
21.         20971520 chars  time: 1513640473.898097661  delta: .199045949
22.         41943040 chars  time: 1513640474.299620758  delta: .401523097
23.         83886080 chars  time: 1513640475.092311556  delta: .792690798
24.        167772160 chars  time: 1513640476.660698221  delta: 1.568386665
25.        335544320 chars  time: 1513640479.776806227  delta: 3.116108006
./append_test.sh: fork: Cannot allocate memory

Ошибки указывают, что мой Bash получил до 335.54432 МБ, прежде чем он упал. Вы можете изменить код с удвоения данных на добавление константы, чтобы получить более детальный график и точку сбоя. Но я думаю, что это должно дать вам достаточно информации, чтобы решить, волнует ли вас это. Лично я ниже 100 МБ. Ваш пробег может варьироваться.

Бруно Броноски
источник
Интересно! Подумайте: join <(LANG=C bash -c 'a="a" c=1 last=${EPOCHREALTIME//.};while :;do a+=$a;now=${EPOCHREALTIME//.};echo $((c++)) ${#a} $((now-last));last=$now;done') <(LANG=C bash -c 'a="a" c=1 last=${EPOCHREALTIME//.};while :;do a=$a$a;now=${EPOCHREALTIME//.};echo $((c++)) ${#a} $((now-last));last=$now;done')|sed -ue '1icnt strlen a+=$a a=$a$a' -e 's/^\([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \2/\1 \2 \3/' | xargs printf "%4s %11s %9s %9s\n"(Попробуйте это на непродуктивном хосте !!;)
Ф. Хаури
4

Я хотел построить строку из списка. Не смог найти ответ на этот вопрос, поэтому я разместил его здесь. Вот что я сделал:

list=(1 2 3 4 5)
string=''

for elm in "${list[@]}"; do
    string="${string} ${elm}"
done

echo ${string}

и тогда я получаю следующий вывод:

1 2 3 4 5
simibac
источник
4

Несмотря на специальный оператор, +=для конкатенации есть более простой путь:

foo='Hello'
foo=$foo' World'
echo $foo

Двойные кавычки требуют дополнительного времени вычисления для интерпретации переменных внутри. Избегайте этого, если это возможно.

Tiys
источник
3

Обратите внимание, что это не сработает

foo=HELLO
bar=WORLD
foobar=PREFIX_$foo_$bar

как кажется, отбрасывает $ foo и оставляет вас с:

PREFIX_WORLD

но это будет работать

foobar=PREFIX_"$foo"_"$bar"

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

PREFIX_HELLO_WORLD

Dss
источник
8
это происходит потому, что подчеркивание является допустимым символом в именах переменных, поэтому bash видит foo_ как переменную. Когда необходимо указать bash точные границы имени переменной, можно использовать фигурные скобки: PREFIX _ $ {foo} _ $ bar
Nik O'Lai
2

Вот один через AWK :

$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
Авинаш Радж
источник
1
Хорошо, но я думаю, что смог бы добиться большей точности, используя Python!
техно,
1

Я делаю это так, когда это удобно: используйте встроенную команду!

echo "The current time is `date`"
echo "Current User: `echo $USER`"
Marty
источник
1
На 1-й строке вы можете сбросить вилку , используя:, date "+The current time is %a %b %d %Y +%T"вместо echo ...$(date). Согласно недавнему Баш, вы могли бы написать: printf "The current time is %(%a %b %d %Y +%T)T\n" -1.
Ф. Хаури
1

На мой взгляд, самый простой способ объединить две строки - написать функцию, которая сделает это за вас, а затем использовать эту функцию.

function concat ()
{
    prefix=$1
    suffix=$2

    echo "${prefix}${suffix}"
}

foo="Super"
bar="man"

concat $foo $bar   # Superman

alien=$(concat $foo $bar)

echo $alien        # Superman
Энтони Ратледж
источник
-1

Мне нравится делать быстрые функции.

#! /bin/sh -f
function combo() {
    echo $@
}

echo $(combo 'foo''bar')

Еще один способ снять кожу с кошки. На этот раз с функциями: D

CommaToast
источник
Вызов функции, который тоже в подоболочке, слишком сложен для простого concat.
Codeforester
-1

Я еще не знаю о PHP, но это работает в Linux Bash. Если вы не хотите влиять на переменную, вы можете попробовать это:

read pp;  *# Assumes I will affect Hello to pp*
pp=$( printf $pp ;printf ' World'; printf '!');
echo $pp;

>Hello World!

Вы можете поместить другую переменную вместо «Hello» или «!». Вы также можете объединить больше строк.

Айман Бублех
источник
2
Использование подоболочки для простой конкатенации слишком дорого!
Codeforester,