Cómo concatenar variables de cadena en Bash

Resuelto Strawberry asked hace 14 años • 30 respuestas

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

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

Aquí, $foose convierte "Hello World".

¿Cómo se logra esto en Bash?

Strawberry avatar Nov 15 '10 12:11 Strawberry
Aceptado
foo="Hello"
foo="${foo} World"
echo "${foo}"
> Hello World

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

a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
codaddict avatar Nov 15 '2010 05:11 codaddict

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

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

producción

XYZ

thkala avatar Nov 15 '2010 08:11 thkala

Golpear primero

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

+=: Agregar a la variable

La sintaxis +=se puede utilizar de diferentes maneras:

Agregar a la cadenavar+=...

(Como soy frugal, solo usaré dos variables fooy aluego reutilizaré las mismas en toda la respuesta. ;-)

a=2
a+=4
echo $a
24

Usando la sintaxis de preguntas de Stack Overflow ,

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

¡funciona bien!

Agregar a un número entero((var+=...))

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

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

Agregar a una matrizvar+=(...)

La nuestra atambién es una matriz 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 contenga 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 !", puedes:

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

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

Donde 6 campos ( oney word4 x hello world!), se agregaron a la matriz ${ar[@]}que ya contenía 38y 18.

printf: Reconstruir la variable usando el comando incorporado

El comando printf incorporado ofrece una forma poderosa de dibujar el formato de cadena. Como se trata de una función incorporada de Bash , existe una opción para enviar una cadena formateada 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á tantos argumentos enviados...

¡ Tenga en cuenta que el nuestro 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 aborda solo el primer elemento!

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!>
<hello world!>

Usando la sintaxis de preguntas de Stack Overflow :

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

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

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

Shell ahora

Bajo el shell POSIX , no se pueden usar bashisms , por lo que no hay ningún archivo incorporado printf .

Básicamente

Pero simplemente podrías hacer:

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

Formateado, usando bifurcación printf

Si desea utilizar construcciones más sofisticadas, debe utilizar una bifurcación (nuevo proceso hijo que realiza el trabajo y devuelve el resultado mediante stdout):

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

Históricamente, se podían utilizar comillas invertidas 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 comillas invertidas, tienes que escapar de las bifurcaciones 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 - Give Up GitHub avatar Aug 04 '2013 10:08 F. Hauri - Give Up GitHub