Cómo concatenar variables de cadena en Bash
En PHP, las cadenas se concatenan de la siguiente manera:
$foo = "Hello";
$foo .= " World";
Aquí, $foo
se convierte "Hello World"
.
¿Cómo se logra esto en Bash?
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
Bash también admite un +=
operador como se muestra en este código:
A="X Y"
A+=" Z"
echo "$A"
producción
XYZ
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 foo
y a
luego 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 a
es una cadena, pero también un número entero
echo $a
24
((a+=12))
echo $a
36
Agregar a una matrizvar+=(...)
La nuestra a
tambié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 ( one
y word
4 x hello world!
), se agregaron a la matriz ${ar[@]}
que ya contenía 38
y 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 a
sigue 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
, tabulations
y/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