Come concatenare le variabili stringa in Bash


2768

In PHP, le stringhe sono concatenate insieme come segue:

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

Qui, $foodiventa "Hello World".

Come si ottiene questo risultato in Bash?


6
foo="Hello" foo=$foo" World" echo $foo questo piuttosto ha funzionato per "#! / bin / sh"
parasparish

1
Cosa fare se si desidera HelloWorld senza spazio?
Adi,

@Adifoo1="World" foo2="Hello" foo3="$foo1$foo2"
GeneCode

spazi fa una questione in bash)
Capibar

Risposte:


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

In generale per concatenare due variabili puoi semplicemente scriverle una dopo l'altra:

a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World

314
Probabilmente bello prendere l'abitudine di mettere $foodentro le doppie virgolette, per i momenti in cui conta davvero.
Cascabel,

104
Ci viene insegnato a farlo sempre perché quando avviene la sostituzione, gli spazi verranno ignorati dalla shell, ma le doppie virgolette proteggeranno sempre quegli spazi.
Fragola,

62
Ci deve essere uno spazio nel tuo primo esempio? È possibile fare qualcosa del genere foo="$fooworld"? Suppongo di no ...
nonsensickle

341
@nonsensickle Sarebbe alla ricerca di una variabile denominata fooworld. Che chiarimento è fatto con le parentesi graffe, come in foo="${foo}world"...
twalberg

4
@ JVE999 Sì, funziona anche così, anche se secondo me non è altrettanto buono per la chiarezza del codice ... Ma questa potrebbe essere solo la mia preferenza ... Ci sono anche un paio di altri modi in cui può essere fatto - il punto è assicurandosi che il nome della variabile sia separato dalle parti senza nome variabile in modo che analizzi correttamente.
twalberg,

1128

Bash supporta anche un +=operatore come mostrato in questo codice:

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

2
Posso usare questa sintassi con la parola chiave export? ad esempio export A+="Z"o forse la Avariabile deve essere esportata una sola volta?
levesque

3
@levesque: Entrambi :-). Le variabili devono essere esportate una sola volta, ma export A+=Zfunzionano altrettanto bene.
thkala,

38
Dato che questo è un bashismo, penso che valga la pena menzionare che non dovresti mai usare #!/bin/shuna sceneggiatura usando questa costruzione.
Score_Under

2
È specificamente e solo un operatore più-uguale. Cioè, a differenza di Javascript, in Bash, l'eco $ A + $ B stampa "X Y + Z"
phpguru,

6
Un bashism è una funzione di shell che è supportata solo in bashe alcune altre shell più avanzate. Non funzionerà sotto busybox sho dash(che è /bin/shsu molte distro), o su alcune altre shell come quelle /bin/shfornite su FreeBSD.
Score_Under

960

Bash prima

Poiché questa domanda è specifica per Bash , la mia prima parte della risposta presenterebbe diversi modi di farlo correttamente:

+=: Aggiungi alla variabile

La sintassi +=può essere utilizzata in diversi modi:

Aggiungi alla stringa var+=...

(Perché io sono frugale, io uso solo due variabili fooe apoi ri-uso la stessa in tutta risposta ;-).

a=2
a+=4
echo $a
24

Utilizzando la sintassi della domanda StackTranslate.it,

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

funziona bene!

Aggiungi a un numero intero ((var+=...))

variabile aè una stringa, ma anche un numero intero

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

Aggiungi a un array var+=(...)

Il nostro aè anche un array di un solo elemento.

echo ${a[@]}
36

a+=(18)

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

Si noti che tra parentesi c'è un array separato da spazi . Se si desidera memorizzare una stringa contenente spazi nell'array, è necessario racchiuderli:

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

Hmm .. questo non è un bug, ma una funzionalità ... Per impedire a bash di provare a svilupparsi !", potresti:

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: Ricostruisci la variabile usando il comando incorporato

Il comando printf incorporato offre un modo potente per disegnare il formato stringa. Poiché si tratta di un built-in di Bash , esiste un'opzione per inviare una stringa formattata a una variabile invece di stampare su stdout:

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

Ci sono sette stringhe in questo array. Quindi potremmo costruire una stringa formattata contenente esattamente sette argomenti posizionali:

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

Oppure potremmo usare una stringa di formato argomento che verrà ripetuta come molti argomenti inviati ...

Nota che il nostro aè ancora un array! Viene modificato solo il primo 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!")'

Sotto bash, quando accedi a un nome di variabile senza specificare l'indice, indirizzi sempre solo il primo elemento!

Quindi, per recuperare il nostro array di sette campi, dobbiamo solo reimpostare il 1 ° 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 stringa di formato argomento con molti argomenti passati a:

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

Utilizzando la sintassi della domanda StackTranslate.it:

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

Nota: l'uso di virgolette doppie può essere utile per manipolare stringhe che contengono spaces, tabulationse / onewlines

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

Shell ora

Nella shell POSIX , non è possibile utilizzare i bashismi , quindi non è incorporato printf .

Fondamentalmente

Ma potresti semplicemente fare:

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

Formattato, usando biforcuta printf

Se si desidera utilizzare costruzioni più sofisticate, è necessario utilizzare una forcella (nuovo processo figlio che esegue il lavoro e restituisce il risultato tramite stdout):

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

Storicamente, è possibile utilizzare i backtick per recuperare il risultato di un fork :

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

Ma questo non è facile per la nidificazione :

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

con le punte posteriori , devi sfuggire alle forcelle interne con barre rovesciate :

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

4
L' +=operatore è anche molto più veloce rispetto $a="$a$b"ai miei test .. Il che ha senso.
Matt,

7
Questa risposta è fantastica, ma penso che manchi l' var=${var}.shesempio di altre risposte, il che è molto utile.
geneorama,

1
È bashl'unica shell con +=operatore? Voglio vedere se è abbastanza portatile
precipitosamente il

1
@dashesy no. sicuramente non è l'unica shell con +=operatore, ma tutti questi modi sono basismi , quindi non portatili! Anche tu potresti riscontrare un bug speciale in caso di versione bash sbagliata!
F. Hauri,

134

Puoi farlo anche tu:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh

4
Sebbene non vengano utilizzati caratteri speciali, né spazi, virgolette doppie, virgolette e parentesi graffe sono inutili: var=myscript;var=$var.sh;echo $varavrebbero gli stessi effetti (Questo lavoro sotto bash, dash, busybox e altri).
F. Hauri,

@ F.Hauri grazie per averlo sottolineato. Ma se dovessi aggiungere un numero, non funzionerebbe: ad es. echo $var2Non producemyscript2
Pynchia

@Pynchia Funziona a causa del punto .illegale nel nome della variabile. Se altro echo ${var}2o vedi la mia risposta
F. Hauri,

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

Verrà emesso

helloohaikthxbye

Ciò è utile quando $blaohai si verifica un errore variabile non trovato. O se hai spazi o altri caratteri speciali nelle tue stringhe. "${foo}"sfugge correttamente a qualsiasi cosa tu ci inserisca.


3
Non funziona Ottengo "backupstorefolder: comando non trovato" da bash dove "backupstorefolder" è il nome di una variabile.
Zian Choy

7
Questo aiuta a evidenziare un po 'la sintassi e rimuove alcune ambiguità umane.
Ray Foss,

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

     


10
Questa è la risposta più utile per gli script di shell. Mi sono ritrovato negli ultimi 30 minuti perché avevo uno spazio prima e dopo il segno uguale !!
Stefan,

8
foo = "$ {foo} World"
XXL

@XXL sicuramente preferirei usare le parentesi quadre per incapsulare il nome di var. Altamente raccomandato
Sergio A.

33

Il modo in cui risolverei il problema è giusto

$a$b

Per esempio,

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

che produce

Hello World

Se provi a concatenare una stringa con un'altra stringa, ad esempio,

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

allora echo "$c"produrrà

Hello World

con uno spazio extra.

$aWorld

non funziona, come puoi immaginare, ma

${a}World

produce

HelloWorld

1
... quindi ${a}\ WorldproduceHello World
XavierStuvw,

Questo mi sorprende; Mi sarei aspettato che c=$a$bqui facessi la stessa cosa c=$a World(che proverebbe a funzionare Worldcome comando). Immagino che ciò significhi che l'assegnazione viene analizzata prima che le variabili vengano espanse ..
mwfearnley,

31

Ecco un breve riassunto di ciò di cui parla la maggior parte delle risposte.

Diciamo che abbiamo due variabili e $ 1 è impostato su 'uno':

set one two
a=hello
b=world

La tabella che segue illustra i diversi contesti in cui siamo in grado di combinare i valori di ae bper creare una nuova variabile, 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

Alcune note:

  • racchiudere l'RHS di un incarico tra virgolette doppie è generalmente una buona pratica, sebbene in molti casi sia del tutto facoltativo
  • += è migliore dal punto di vista delle prestazioni se una stringa grande viene costruita in piccoli incrementi, specialmente in un ciclo
  • usa {}attorno ai nomi delle variabili per chiarire la loro espansione (come nella riga 2 nella tabella sopra). Come si vede nelle righe 3 e 4, non è necessario a {}meno che una variabile non sia concatenata con una stringa che inizia con un carattere che è un primo carattere valido nel nome della variabile di shell, ovvero alfabeto o carattere di sottolineatura.

Guarda anche:


2
Se siete preoccupati per le prestazioni, vedere un'analisi nella mia risposta stackoverflow.com/a/47878161/117471
Bruno Bronosky

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

20

Ancora un altro approccio ...

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

... e ancora un altro ancora.

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

1
Questo è quello che ho fatto, e l'ho trovato molto semplice e diretto rispetto alle altre risposte. C'è un motivo per cui nessuno delle risposte più votate ha sottolineato questa opzione?
Quimnuss,

1
@quimnuss Il fatto che le stringhe non corrispondano a quelle utilizzate nella domanda OP potrebbe essere una buona ragione.
jlliagre,

20

Se vuoi aggiungere qualcosa come un trattino basso, usa escape (\)

FILEPATH=/opt/myfile

Questo non funziona:

echo $FILEPATH_$DATEX

Funziona bene:

echo $FILEPATH\\_$DATEX

11
O in alternativa, $ {FILEPATH} _ $ DATEX. Qui {} vengono utilizzati per indicare i confini del nome della variabile. Questo è appropriato perché il carattere di sottolineatura è un carattere legale nei nomi delle variabili, quindi nel tuo frammento bash in realtà cerca di risolvere FILEPATH_, non solo $ FILEPATH
Nik O'Lai,

1
per me avevo una variabile, vale a dire $ var1 e costante accanto a questa, quindi echo $ var1_costant_traling_part funziona per me
YouAreAwesome

2
Immagino che per scappare sia necessario solo un gioco: echo $a\_$bfarebbe. Come accennato nel commento di Nik O'Lai il carattere di sottolineatura è un personaggio regolare. La gestione degli spazi bianchi è molto più sensibile alle stringhe, all'eco e alla concatenazione --- si può usare \ e leggere attentamente questa discussione poiché questo problema ritorna di tanto in tanto.
XavierStuvw,

16

Il modo più semplice con le virgolette:

B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"

1
Troppe virgolette, IMHO. var=$B$b"a"; echo Hello\ $varfarei, credo
XavierStuvw,

Suggerisco di usare tutte le virgolette, perché se lo metti ovunque non puoi perderlo, non devi pensare.
betontalpfa,

15

Puoi concatenare senza virgolette. Ecco un esempio:

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

Quest'ultima affermazione stampa "OpenSystems" (senza virgolette).

Questo è un esempio di uno script Bash:

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

1
La sintassi del primo blocco è confusa. Cosa significano questi segni $?
XavierStuvw,

15

Anche se l'operatore + = è ora consentito, è stato introdotto in Bash 3.1 nel 2004.

Qualsiasi script che utilizza questo operatore su versioni precedenti di Bash fallirà con un errore "comando non trovato" se sei fortunato, o un "errore di sintassi vicino a token imprevisto".

Per coloro a cui interessa la compatibilità con le versioni precedenti, attenersi ai metodi di concatenazione Bash standard più vecchi, come quelli menzionati nella risposta scelta:

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

1
Grazie per averlo sottolineato, stavo solo cercando quale versione è necessaria affinché questo funzioni.
Rho Phi,

14

Preferisco usare parentesi graffe ${}per espandere la variabile nella stringa:

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

Le parentesi graffe si adatteranno all'utilizzo continuo di stringhe:

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

Altrimenti l'utilizzo foo = "$fooWorld"non funzionerà.


8

Se quello che stai cercando di fare è dividere una stringa in più righe, puoi usare una barra rovesciata:

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

Con uno spazio in mezzo:

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

Questo aggiunge anche solo uno spazio tra:

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

Temo che non intendesse questo
installero il

7

Modo più sicuro:

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

Le stringhe contenenti spazi possono diventare parte del comando, utilizzare "$ XXX" e "$ {XXX}" per evitare questi errori.

Inoltre, dai un'occhiata ad altre risposte su + =


Il punto delle stringhe con uno spazio che viene letto come comando viene visualizzato nel punto di definizione. Quindi d=DD DDdarei DD: command not found--- nota che è l'ultimo DD, piuttosto d che non viene trovato. Se tutti gli operandi sono formattati correttamente e contengono già gli spazi richiesti, puoi semplicemente concatenarli s=${a}${b}${c}${d}; echo $s, con meno virgolette. Inoltre, è possibile utilizzare \ (spazi bianchi di escape) per evitare questi problemi --- d=echo\ echonon avvierà alcuna invocazione di eco, mentre lo d=echo echofarà.
XavierStuvw,

7

C'è un caso particolare in cui dovresti prenderti cura:

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

Produrrà "daniel"sane non danielsan, come avresti potuto desiderare. In questo caso dovresti invece fare:

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

6
a="Hello,"
a=$a" World!"
echo $a

Ecco come concatenare due stringhe.


1
Funziona, ma a volte produrrà risultati imprevedibili perché l'interpolazione variabile non è protetta. Pertanto, non è possibile fare affidamento su questo modulo per tutti i casi d'uso.
Anthony Rutledge,

5

Se è come il tuo esempio di aggiunta " World"alla stringa originale, allora può essere:

#!/bin/bash

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

Il risultato:

Hello World

5
var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3

2
Ha anche var3=$var1\ $var2lo stesso effetto
XavierStuvw,

5

Esistono preoccupazioni espresse in merito alle prestazioni, ma non vengono offerti dati. Lasciami suggerire un semplice test.

(NOTA: date su macOS non offre nanosecondi, quindi questo deve essere fatto su Linux.)

Ho creato append_test.sh su GitHub con i contenuti:

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

Test 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

Test 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

Gli errori indicano che il mio Bash è arrivato a 335.54432 MB prima che si schiantasse. È possibile modificare il codice dal raddoppio dei dati all'aggiunta di una costante per ottenere un grafico più granulare e un punto di errore. Ma penso che questo dovrebbe darti abbastanza informazioni per decidere se ti interessa. Personalmente, sotto i 100 MB non lo faccio. Il tuo chilometraggio può variare.


Interessante! Considera: 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"(Prova questo su host non produttivo !!;)
F. Hauri,

4

Volevo costruire una stringa da un elenco. Non ho trovato una risposta per questo, quindi la pubblico qui. Ecco cosa ho fatto:

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

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

echo ${string}

e quindi ottengo il seguente output:

1 2 3 4 5

4

Nonostante l'operatore speciale +=, per la concatenazione, esiste un modo più semplice di procedere:

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

Le virgolette doppie richiedono un tempo di calcolo aggiuntivo per l'interpretazione delle variabili all'interno. Evitalo se possibile.


3

Nota che questo non funzionerà

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

come sembra far cadere $ foo e ti lascia con:

PREFIX_WORLD

ma questo funzionerà:

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

e lasciarti con l'output corretto:

PREFIX_HELLO_WORLD


8
questo accade perché il trattino basso è il carattere valido nei nomi delle variabili, quindi bash vede foo_ come una variabile. Quando è necessario dire a bash i limiti esatti del nome var, è possibile utilizzare le parentesi graffe: PREFIX _ $ {foo} _ $ bar
Nik O'Lai

2

Ecco quello attraverso AWK :

$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World

1
Bello, ma penso che potrei ottenere più precisione usando Python!
techno,

1

Lo faccio in questo modo quando comodo: usa un comando in linea!

echo "The current time is `date`"
echo "Current User: `echo $USER`"

1
Alla prima riga, è possibile rilasciare un fork utilizzando:, date "+The current time is %a %b %d %Y +%T"anziché echo ...$(date). Sotto recente bash, si potrebbe scrivere: printf "The current time is %(%a %b %d %Y +%T)T\n" -1.
F. Hauri,

1

Secondo me, il modo più semplice per concatenare due stringhe è scrivere una funzione che lo fa per te, quindi utilizzare quella funzione.

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

Mi piace fare una funzione veloce.

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

echo $(combo 'foo''bar')

Ancora un altro modo di scuoiare un gatto. Questa volta con funzioni: D


Chiamare una funzione, anche quella in una subshell, è eccessivo per un semplice concat.
codeforester

-1

Non conosco ancora PHP, ma funziona con Linux Bash. Se non si desidera influire su una variabile, è possibile provare questo:

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

>Hello World!

È possibile posizionare un'altra variabile anziché "Ciao" o "!". Potresti concatenare anche più stringhe.


2
L'uso di una subshell per eseguire una semplice concatenazione è troppo costoso!
codeforester
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.