Cómo concatenar variables de cadena en Bash

2769

En PHP, las cadenas se concatenan juntas de la siguiente manera:

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

Aquí, se $fooconvierte en "Hola Mundo".

¿Cómo se logra esto en Bash?

fresa
fuente
66
foo="Hello" foo=$foo" World" echo $foo esto funcionó más bien para "#! / bin / sh"
parásito
1
¿Qué hacer si quieres HelloWorld sin espacio?
Adi
@Adifoo1="World" foo2="Hello" foo3="$foo1$foo2"
GeneCode
espacios hace un problema en bash)
Capibar

Respuestas:

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

En general, para concatenar dos variables, puede escribirlas una tras otra:

a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
codictorio
fuente
314
Probablemente sea bueno tener el hábito de poner $foodentro de las comillas dobles, para los momentos en que realmente importa.
Cascabel
104
Se nos enseña a hacerlo siempre porque cuando se realiza la sustitución, los espacios serán ignorados por el shell, pero las comillas dobles siempre protegerán esos espacios.
Fresa
6262
¿Tiene que haber un espacio en su primer ejemplo? ¿Es posible hacer algo así foo="$fooworld"? Supongo que no ...
nonsensickle
341
@nonsensickle Eso buscaría una variable llamada fooworld. Disambiguating que se hace con llaves, como en foo="${foo}world"...
twalberg
44
@ JVE999 Sí, eso también funciona, aunque en mi opinión no es tan bueno para la claridad del código ... Pero esa puede ser mi preferencia ... También hay un par de otras formas en que se puede hacer: el punto es asegurándose de que el nombre de la variable esté separado de las partes que no son de nombre variable para que se analice correctamente.
twalberg
1128

Bash también admite un +=operador como se muestra en este código:

$ A="X Y"
$ A+=" Z"
$ echo "$A"
X Y Z
thkala
fuente
2
¿Puedo usar esta sintaxis con la palabra clave exportar? por ejemplo, ¿ export A+="Z"o tal vez la Avariable solo necesita exportarse una vez?
Levesque
3
@levesque: Ambos :-). Las variables solo necesitan exportarse una vez, pero también export A+=Zfuncionan bastante bien.
thkala
38
Como se trata de un bashism, creo que vale la pena mencionar que nunca deberías usar #!/bin/shen un script que use esta construcción.
Score_Under
2
Es específicamente y solo un operador más-igual. Es decir, a diferencia de Javascript, en Bash, echo $ A + $ B imprime "X Y + Z"
phpguru
66
Un bashism es una función de shell que solo es compatible con bashciertos shells más avanzados. No funcionará bajo busybox sho dash(que está /bin/shen muchas distribuciones), o ciertos otros shells como el /bin/shproporcionado en FreeBSD.
Score_Under
960

Bash primero

Como esta pregunta se refiere específicamente a Bash , mi primera parte de la respuesta presentaría diferentes formas de hacerlo correctamente:

+=: Añadir a variable

La sintaxis +=se puede usar de diferentes maneras:

Añadir a cadena var+=...

(Porque soy frugal, que sólo utilizará dos variables fooy ay luego volver a utilizar la misma en toda la respuesta. ;-)

a=2
a+=4
echo $a
24

Usando la sintaxis de preguntas de desbordamiento de pila ,

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

¡funciona bien!

Agregar a un entero ((var+=...))

variable aes una cadena, pero también un número entero

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

Agregar a una matriz var+=(...)

El nuestro atambién es un conjunto de un solo elemento.

echo ${a[@]}
36

a+=(18)

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

Tenga en cuenta que entre paréntesis, hay una matriz separada por espacios . Si desea almacenar una cadena que contiene espacios en su matriz, debe encerrarlos:

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

Hmm ... esto no es un error, sino una característica ... Para evitar que bash intente desarrollarse !", podría:

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: Reconstruir variable usando el comando incorporado

El comando printf incorporado ofrece una forma poderosa de dibujar el formato de cadena. Como se trata de un Bash incorporado , hay una opción para enviar cadenas formateadas a una variable en lugar de imprimir en stdout:

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

Hay siete cadenas en esta matriz. Entonces podríamos construir una cadena formateada que contenga exactamente siete argumentos posicionales:

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

O podríamos usar una cadena de formato de argumento que se repetirá como muchos argumentos enviados ...

Tenga en cuenta que nuestra asigue siendo una matriz! ¡Solo se cambia el primer elemento!

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!")'

En bash, cuando accede a un nombre de variable sin especificar el índice, ¡siempre se dirige al primer elemento solamente!

Entonces, para recuperar nuestra matriz de siete campos, solo necesitamos restablecer el primer elemento:

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!")'

Una cadena de formato de argumento con muchos argumentos pasados ​​a:

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

Usando la sintaxis de preguntas de desbordamiento de pila :

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

Nota: El uso de comillas dobles puede ser útil para manipular cadenas que contienen spaces, tabulationsy / onewlines

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

Shell ahora

En el shell POSIX , no puede usar bashisms , por lo que no hay incorporado printf .

Básicamente

Pero simplemente podrías hacer:

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

Formateado, utilizando bifurcado printf

Si desea usar construcciones más sofisticadas, debe usar una bifurcación (nuevo proceso secundario que hace el trabajo y devuelve el resultado a través de stdout):

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

Históricamente, podría usar los backticks para recuperar el resultado de una bifurcación :

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

Pero esto no es fácil para anidar :

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

con backticks, debes escapar de las horquillas internas con barras invertidas :

foo="Today is: "
foo=`printf "%s %s" "$foo" "\`date\`"`
echo $foo
Today is: Sun Aug 4 11:59:10 CEST 2013
F. Hauri
fuente
44
El +=operador también es mucho más rápido que $a="$a$b"en mis pruebas. Lo cual tiene sentido.
Matt
77
Esta respuesta es increíble, pero creo que le falta el var=${var}.shejemplo de otras respuestas, lo cual es muy útil.
geneorama
1
¿Es bashel único shell con +=operador? Quiero ver si es lo suficientemente portátil
guioneso
1
@dashesy no. seguramente no es el único shell con +=operador, pero todas estas formas son bashismos , ¡así que no son portátiles! ¡Incluso podría encontrar un error especial en caso de una versión incorrecta de bash!
F. Hauri
134

También puedes hacer esto:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh
tendencia de uso
fuente
44
Si bien no se utilizan caracteres especiales ni espacios, las comillas dobles, las comillas y las llaves son inútiles: var=myscript;var=$var.sh;echo $vartendrían los mismos efectos (esto funciona en bash, dash, busybox y otros).
F. Hauri
@ F.Hauri gracias por señalar eso. Pero si tuviera que agregar un número, no funcionaría: por ejemplo echo $var2, no producemyscript2
Pynchia
@Pynchia Esto funciona debido al punto .ilegal en el nombre de la variable. Si más echo ${var}2o ver mi respuesta
F. Hauri
119
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"

Saldrá

helloohaikthxbye

Esto es útil cuando $blaohai conduce a un error de variable no encontrada. O si tiene espacios u otros caracteres especiales en sus cadenas. "${foo}"escapa correctamente de todo lo que pones en él.

orkoden
fuente
3
No funciona Obtengo "backupstorefolder: comando no encontrado" de bash donde "backupstorefolder" es el nombre de una variable.
Zian Choy
77
Esto ayuda a resaltar bastante la sintaxis y elimina la ambigüedad humana.
Ray Foss
44
foo="Hello "
foo="$foo World"

     

vinothkr
fuente
10
Esta es la respuesta más útil para los scripts de shell. ¡¡Me encontré los últimos 30 minutos porque tuve un espacio antes y después del signo igual !!
Stefan
8
foo = "$ {foo} Mundo"
XXL
@XXL seguramente preferiría usar corchetes para encapsular el nombre de var. Muy recomendable
Sergio A.
33

La forma en que resolvería el problema es simplemente

$a$b

Por ejemplo,

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

que produce

Hello World

Si intenta concatenar una cadena con otra cadena, por ejemplo,

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

entonces echo "$c"producirá

Hello World

Con un espacio extra.

$aWorld

no funciona, como te puedes imaginar, pero

${a}World

produce

HelloWorld
Chris Smith
fuente
1
... por lo tanto ${a}\ WorldproduceHello World
XavierStuvw
Esto me sorprende Hubiera esperado c=$a$bque hiciera lo mismo que c=$a World(que intentaría ejecutarse Worldcomo un comando). Supongo que eso significa que la cesión se procesadas antes que se expanden las variables ..
mwfearnley
31

Aquí hay un resumen conciso de lo que están hablando la mayoría de las respuestas.

Digamos que tenemos dos variables y $ 1 se establece en 'uno':

set one two
a=hello
b=world

La siguiente tabla explica los diferentes contextos en los que podemos combinar los valores de ay bpara crear una nueva variable, 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

Algunas notas

  • encerrar el RHS de una tarea entre comillas dobles es generalmente una buena práctica, aunque es bastante opcional en muchos casos
  • += es mejor desde el punto de vista del rendimiento si se construye una cadena grande en pequeños incrementos, especialmente en un bucle
  • use {}alrededor de nombres de variables para desambiguar su expansión (como en la fila 2 de la tabla anterior). Como se ve en las filas 3 y 4, no es necesario a {}menos que una variable se concatene con una cadena que comienza con un carácter que es un primer carácter válido en el nombre de la variable de shell, es decir, alfabeto o guión bajo.

Ver también:

codeforester
fuente
2
Si le preocupa el rendimiento, vea un análisis en mi respuesta stackoverflow.com/a/47878161/117471
Bruno Bronosky
29
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
bcosca
fuente
20

Otro enfoque más ...

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

... y otro más.

> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.
Akseli Palén
fuente
1
Eso es lo que hice, y lo encontré mucho más simple y directo que las otras respuestas. ¿Hay alguna razón por la cual nadie en las respuestas más votadas señaló esta opción?
quimnuss
1
@quimnuss El hecho de que las cadenas no coincidan con las utilizadas en la pregunta OP podría ser una buena razón.
jlliagre el
20

Si desea agregar algo como un guión bajo, use escape (\)

FILEPATH=/opt/myfile

Esto no funciona:

echo $FILEPATH_$DATEX

Esto funciona bien:

echo $FILEPATH\\_$DATEX
usuario2800471
fuente
11
O, alternativamente, $ {FILEPATH} _ $ DATEX. Aquí {} se utilizan para indicar los límites del nombre de la variable. Esto es apropiado porque el guión bajo es un carácter legal en los nombres de variables, por lo que en su fragmento de código intenta realmente resolver FILEPATH_, no solo $ FILEPATH
Nik O'Lai
1
para mí tenía una variable, es decir, $ var1 y constante al lado de esto, por lo que echo $ var1_costant_traling_part funciona para mí
YouAreAwesome
2
Supongo que uno solo necesita una reacción violenta para escapar: echo $a\_$blo haría. Como se insinuó en el comentario de Nik O'Lai, el guión bajo es un personaje normal. El manejo de los espacios en blanco es mucho más sensible para las cadenas, el eco y la concatenación: se puede usar \ y leer este hilo a fondo a medida que este problema vuelve de vez en cuando.
XavierStuvw
16

La forma más simple con comillas:

B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
betontalpfa
fuente
1
Demasiadas comillas, en mi humilde opinión. var=$B$b"a"; echo Hello\ $varharía, creo
XavierStuvw
Sugiero usar todas las comillas, porque si lo pones en todas partes no te lo puedes perder, no tienes que pensar.
betontalpfa
15

Puedes concatenar sin las comillas. Aquí hay un ejemplo:

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

Esta última declaración imprimiría "OpenSystems" (sin comillas).

Este es un ejemplo de un script Bash:

v1=hello
v2=world
v3="$v1       $v2"
echo $v3            # Output: hello world
echo "$v3"          # Output: hello       world
mariana más suave
fuente
1
La sintaxis del primer bloque es confusa. ¿Qué significan estos signos $?
XavierStuvw
15

Incluso si el operador + = ahora está permitido, se introdujo en Bash 3.1 en 2004.

Cualquier script que use este operador en versiones anteriores de Bash fallará con un error de "comando no encontrado" si tiene suerte, o un "error de sintaxis cerca de un token inesperado".

Para aquellos que se preocupan por la compatibilidad con versiones anteriores, quédese con los métodos de concatenación Bash estándar más antiguos, como los mencionados en la respuesta elegida:

foo="Hello"
foo="$foo World"
echo $foo
> Hello World
Louis-Félix
fuente
1
Gracias por señalar esto, solo estaba buscando qué versión se requiere para que esto funcione.
Rho Phi
14

Prefiero usar llaves ${}para expandir la variable en cadena:

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

Las llaves se ajustarán al uso continuo de cadenas:

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

De lo contrario, el uso foo = "$fooWorld"no funcionará.

Nick Tsai
fuente
8

Si lo que intenta hacer es dividir una cadena en varias líneas, puede usar una barra invertida:

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

Con un espacio en el medio:

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

Este también agrega solo un espacio intermedio:

$ a="hello \
>      world"
$ echo $a
hello world
jcarballo
fuente
Me temo que esto no es lo que quería decir
installero
7

Forma más segura:

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

Las cadenas que contienen espacios pueden formar parte del comando, use "$ XXX" y "$ {XXX}" para evitar estos errores.

Además, mira otra respuesta sobre + =

Bohdan
fuente
El punto de las cadenas con un espacio que se lee como un comando aparece en el punto de definición. Entonces d=DD DDdaría DD: command not found--- nota que es el último DD, más bien d que no se encuentra. Si todos los operandos están formateados correctamente y ya contienen los espacios requeridos, simplemente puede concatenar s=${a}${b}${c}${d}; echo $scon menos comillas. También podría usar \ (espacios en blanco escapados) para evitar estos problemas --- d=echo\ echono lanzará ninguna invocación de eco, mientras que lo d=echo echohará.
XavierStuvw
7

Hay un caso particular en el que debes tener cuidado:

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

Saldrá "daniel"san, y no danielsan, como podría haber querido. En este caso, deberías hacer en su lugar:

user=daniel
cat > output.file << EOF
${user}san
EOF
diogovk
fuente
6
a="Hello,"
a=$a" World!"
echo $a

Así es como se concatenan dos cadenas.

CodeNinjaPI
fuente
1
Esto funciona, pero a veces arrojará resultados impredecibles porque la interpolación variable no está protegida. Por lo tanto, no puede confiar en este formulario para todos los casos de uso.
Anthony Rutledge
5

Si es como su ejemplo de agregar " World"a la cadena original, entonces puede ser:

#!/bin/bash

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

La salida:

Hello World
nonopolaridad
fuente
5
var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3
hari
fuente
2
También var3=$var1\ $var2tiene el mismo efecto
XavierStuvw
5

Hay preocupaciones expresadas sobre el rendimiento, pero no se ofrecen datos. Déjame sugerirte una prueba simple.

(NOTA: dateen macOS no ofrece nanosegundos, por lo que debe hacerse en Linux).

He creado append_test.sh en GitHub con el contenido:

#!/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

Prueba 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

Prueba 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

Los errores indican que mi Bash llegó a 335.54432 MB antes de que se bloqueara . Puede cambiar el código de duplicar los datos a agregar una constante para obtener un gráfico más detallado y un punto de falla. Pero creo que esto debería darle suficiente información para decidir si le importa. Personalmente, menos de 100 MB no. Su experiencia puede ser diferente.

Bruno Bronosky
fuente
¡Interesante! Considere: 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"(¡Pruebe esto en un host no productivo
!;
4

Quería construir una cadena de una lista. No pude encontrar una respuesta para eso, así que lo publico aquí. Aquí esta lo que hice:

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

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

echo ${string}

y luego obtengo el siguiente resultado:

1 2 3 4 5
simibac
fuente
4

A pesar del operador especial +=, para la concatenación, hay un camino más simple:

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

Las comillas dobles requieren un tiempo de cálculo adicional para la interpretación de las variables internas. Evítalo si es posible.

Tiys
fuente
3

Tenga en cuenta que esto no funcionará

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

ya que parece caer $ foo y te deja con:

PREFIX_WORLD

pero esto funcionará:

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

y te dejo con la salida correcta:

PREFIX_HELLO_WORLD

Dss
fuente
8
Esto sucede porque el guión bajo es el carácter válido en los nombres de las variables, por lo que bash ve a foo_ como una variable. Cuando es necesario decirle a bash los límites exactos del nombre de var, se pueden usar las llaves: PREFIJO _ $ {foo} _ $ bar
Nik O'Lai
2

Aquí está el de AWK :

$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
Avinash Raj
fuente
1
Bien, ¡pero creo que podría obtener más precisión usando Python!
techno
1

Lo hago de esta manera cuando sea conveniente: ¡use un comando en línea!

echo "The current time is `date`"
echo "Current User: `echo $USER`"
Marty
fuente
1
En la primera línea, puede soltar un tenedor usando:, en date "+The current time is %a %b %d %Y +%T"lugar de echo ...$(date). Bajo reciente fiesta, se podría escribir: printf "The current time is %(%a %b %d %Y +%T)T\n" -1.
F. Hauri
1

En mi opinión, la forma más sencilla de concatenar dos cadenas es escribir una función que lo haga por usted y luego usar esa función.

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

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

foo="Super"
bar="man"

concat $foo $bar   # Superman

alien=$(concat $foo $bar)

echo $alien        # Superman
Anthony Rutledge
fuente
-1

Me gusta hacer una función rápida.

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

echo $(combo 'foo''bar')

Otra forma más de pelar un gato. Esta vez con funciones: D

Tostada de coma
fuente
Llamar a una función, eso también en una subshell, es demasiado exagerado para un simple concat.
codeforester
-1

Todavía no sé sobre PHP, pero esto funciona en Linux Bash. Si no desea afectarlo a una variable, puede intentar esto:

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

>Hello World!

Podría colocar otra variable en lugar de 'Hola' o '!'. También podría concatenar más cadenas.

Ayman Boubleh
fuente
2
¡Usar un subshell para hacer una concatenación simple es demasiado costoso!
codeforester