Comment concaténer des variables de chaîne dans Bash


2769

En PHP, les chaînes sont concaténées comme suit:

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

Ici, $foodevient "Hello World".

Comment cela se fait-il dans Bash?


6
foo="Hello" foo=$foo" World" echo $foo cela a plutôt fonctionné pour "#! / bin / sh"
parasrish

1
Que faire si vous voulez HelloWorld sans espace?
Adi

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

les espaces sont importants en bash)
Capibar

Réponses:


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

En général, pour concaténer deux variables, vous pouvez simplement les écrire l'une après l'autre:

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

314
Probablement bon de prendre l'habitude de mettre $foodes guillemets doubles, pour les moments où cela compte vraiment.
Cascabel

104
On nous apprend à toujours faire cela car lorsque la substitution a lieu, les espaces seront ignorés par le shell, mais les guillemets doubles protégeront toujours ces espaces.
Fraise

62
Doit-il y avoir un espace dans votre premier exemple? Est-il possible de faire quelque chose comme ça foo="$fooworld"? Je suppose que non ...
nonsensickle

341
@nonsensickle Cela rechercherait une variable nommée fooworld. Sans ambiguïté, cela se fait avec des accolades, comme dans foo="${foo}world"...
twalberg

4
@ JVE999 Oui, cela fonctionne aussi bien, mais à mon avis, ce n'est pas aussi bon pour la clarté du code ... Mais c'est peut-être ma préférence ... Il y a deux autres façons de le faire aussi - le fait est en s'assurant que le nom de variable est séparé des parties non nom-variable afin qu'il analyse correctement.
twalberg

1128

Bash prend également en charge un +=opérateur comme indiqué dans ce code:

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

2
Puis-je utiliser cette syntaxe avec le mot-clé d'exportation? par exemple export A+="Z"ou peut-être que la Avariable ne doit être exportée qu'une seule fois?
levesque

3
@levesque: Les deux :-). Les variables ne doivent être exportées qu'une seule fois, mais export A+=Zfonctionnent également très bien.
thkala

38
Comme il s'agit d'un bashisme, je pense qu'il vaut la peine de mentionner que vous ne devriez jamais utiliser #!/bin/shdans un script utilisant cette construction.
Score_Under

2
C'est spécifiquement et seulement un opérateur plus-égal. Autrement dit, contrairement à Javascript, dans Bash, l'écho $ A + $ B imprime "X Y + Z"
phpguru

6
Un bashisme est une fonction shell qui n'est prise en charge que dans bashcertains autres shell plus avancés. Il ne fonctionnera pas sous busybox shou dash(qui est /bin/shsur beaucoup de distributions), ou certains autres shells comme ceux /bin/shfournis sur FreeBSD.
Score_Under

960

Bash first

Comme cette question concerne spécifiquement Bash , ma première partie de la réponse présenterait différentes façons de le faire correctement:

+=: Ajouter à la variable

La syntaxe +=peut être utilisée de différentes manières:

Ajouter à la chaîne var+=...

(Parce que je suis frugal, je ne l' utilise deux variables fooet apuis réutiliser le même dans toute la réponse. ;-)

a=2
a+=4
echo $a
24

En utilisant la syntaxe de question Stack Overflow ,

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

fonctionne bien!

Ajouter à un entier ((var+=...))

variable aest une chaîne, mais aussi un entier

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

Ajouter à un tableau var+=(...)

Notre aest également un tableau d'un seul élément.

echo ${a[@]}
36

a+=(18)

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

Notez qu'entre parenthèses, il y a un tableau séparé par des espaces . Si vous souhaitez stocker une chaîne contenant des espaces dans votre tableau, vous devez les entourer:

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

Hmm .. ce n'est pas un bug, mais une fonctionnalité ... Pour empêcher bash d'essayer de se développer !", vous pourriez:

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: Reconstruire la variable à l'aide de la commande intégrée

La commande printf intégrée donne un moyen puissant de dessiner le format de chaîne. Comme il s'agit d'un Bash intégré , il existe une option pour envoyer une chaîne formatée à une variable au lieu d'imprimer sur stdout:

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

Il y a sept chaînes dans ce tableau. Nous pourrions donc construire une chaîne formatée contenant exactement sept arguments positionnels:

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

Ou nous pourrions utiliser une chaîne de format d'argument qui sera répétée autant d'arguments soumis ...

Notez que notre aest toujours un tableau! Seul le premier élément est modifié!

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

Sous bash, lorsque vous accédez à un nom de variable sans spécifier d'index, vous n'adressez toujours que le premier élément!

Donc, pour récupérer notre tableau à sept champs, il suffit de réinitialiser le 1er élément:

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

Une chaîne de format d'argument avec plusieurs arguments passés à:

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

Utilisation de la syntaxe de question Stack Overflow :

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

Nota: L'utilisation des guillemets doubles peut être utile pour manipuler des chaînes qui contiennent spaces, tabulationset / ounewlines

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

Shell maintenant

Sous le shell POSIX , vous ne pouviez pas utiliser de bashismes , il n'y a donc pas de fonction intégrée printf .

Fondamentalement

Mais vous pourriez simplement faire:

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

Formaté, en utilisant fourchue printf

Si vous souhaitez utiliser des constructions plus sophistiquées, vous devez utiliser un fork (nouveau processus enfant qui fait le travail et renvoie le résultat via stdout):

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

Historiquement, vous pouviez utiliser des backticks pour récupérer le résultat d'un fork :

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

Mais ce n'est pas facile pour l' imbrication :

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

avec des contre-coups, vous devez échapper aux fourches intérieures avec des contre - obliques :

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

4
L' +=opérateur est également beaucoup plus rapide que $a="$a$b"dans mes tests .. Ce qui est logique.
Matt

7
Cette réponse est géniale, mais je pense qu'il manque l' var=${var}.shexemple des autres réponses, ce qui est très utile.
geneorama

1
Est bashle seul shell avec +=opérateur? Je veux voir s'il est suffisamment portable
dashesy

1
@dashesy no. ce n'est sûrement pas le seul shell avec +=opérateur, mais tous ces moyens sont des bashismes , donc pas portables! Même vous pourriez rencontrer un bug spécial en cas de mauvaise version bash!
F.Hauri

134

Vous pouvez le faire aussi:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh

4
Bien qu'aucun caractère spécial, ni espace ne soit utilisé, les guillemets doubles, les guillemets et les accolades sont inutiles: var=myscript;var=$var.sh;echo $varauraient les mêmes effets (cela fonctionne sous bash, dash, busybox et autres).
F. Hauri

@ F.Hauri merci de l'avoir signalé. Mais si vous deviez ajouter un numéro, cela ne fonctionnerait pas: par exemple, echo $var2ne produit pasmyscript2
Pynchia

@Pynchia Cela fonctionne à cause du point .illégal dans le nom de variable. Sinon echo ${var}2ou voir ma réponse
F. Hauri

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

Sortira

helloohaikthxbye

Ceci est utile lorsque $blaohai conduit à une erreur de variable non trouvée. Ou si vous avez des espaces ou d'autres caractères spéciaux dans vos chaînes. "${foo}"échappe correctement tout ce que vous y mettez.


3
Ça ne marche pas. J'obtiens "backupstorefolder: commande introuvable" de bash où "backupstorefolder" est le nom d'une variable.
Zian Choy

7
Cela aide à mettre en évidence la syntaxe un peu, et supprime une certaine ambiguïté humaine.
Ray Foss du

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

     


10
C'est la réponse la plus utile pour les scripts shell. Je me suis retrouvé les 30 dernières minutes car j'avais un espace avant et après le signe égal !!
Stefan

8
foo = "$ {foo} World"
XXL

@XXL Je préfère sûrement utiliser des crochets pour encapsuler le nom de var. Fortement recommandé
Sergio A.

33

La façon dont je résoudrais le problème est simplement

$a$b

Par exemple,

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

qui produit

Hello World

Si vous essayez de concaténer une chaîne avec une autre chaîne, par exemple,

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

puis echo "$c"produira

Hello World

avec un espace supplémentaire.

$aWorld

ne fonctionne pas, comme vous pouvez l'imaginer, mais

${a}World

produit

HelloWorld

1
... donc ${a}\ WorldproduitHello World
XavierStuvw

Cela me surprend; Je me serais attendu c=$a$bici à faire la même chose que c=$a World(qui essaierait de fonctionner Worldcomme une commande). Je suppose que cela signifie que l'affectation est analysée avant que les variables ne soient développées ..
mwfearnley

31

Voici un résumé concis de ce dont parlent la plupart des réponses.

Disons que nous avons deux variables et que $ 1 est réglé sur «un»:

set one two
a=hello
b=world

Le tableau ci - dessous explique les différents contextes où l' on peut combiner les valeurs aet bde créer une nouvelle 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

Quelques notes:

  • mettre le RHS d'une affectation entre guillemets est généralement une bonne pratique, bien qu'elle soit tout à fait facultative dans de nombreux cas
  • += est meilleur du point de vue des performances si une grosse chaîne est construite en petits incréments, en particulier dans une boucle
  • utilisez {}autour des noms de variables pour lever l'ambiguïté de leur expansion (comme dans la ligne 2 du tableau ci-dessus). Comme on le voit sur les lignes 3 et 4, il n'est pas nécessaire {}sauf si une variable est concaténée avec une chaîne qui commence par un caractère qui est un premier caractère valide dans le nom de la variable shell, c'est-à-dire l'alphabet ou le trait de soulignement.

Voir également:


2
Si vous êtes préoccupé par les performances, consultez une analyse dans ma réponse stackoverflow.com/a/47878161/117471
Bruno Bronosky

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

20

Encore une autre approche ...

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

... et encore un autre.

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

1
C'est ce que j'ai fait et je l'ai trouvé tellement simple et direct que les autres réponses. Y a-t-il une raison pour laquelle personne sur les réponses les plus votées n'a signalé cette option?
quimnuss

1
@quimnuss Le fait que les chaînes ne correspondent pas à celles utilisées dans la question OP peut être une bonne raison.
jlliagre

20

Si vous souhaitez ajouter quelque chose comme un trait de soulignement, utilisez escape (\)

FILEPATH=/opt/myfile

Cela ne fonctionne pas :

echo $FILEPATH_$DATEX

Cela fonctionne bien:

echo $FILEPATH\\_$DATEX

11
Ou bien, $ {FILEPATH} _ $ DATEX. Ici, {} sont utilisés pour indiquer les limites du nom de la variable. Ceci est approprié car le trait de soulignement est un caractère légal dans les noms de variable, donc dans votre extrait de code bash essaie en fait de résoudre FILEPATH_, pas seulement $ FILEPATH
Nik O'Lai

1
pour moi, j'avais une variable, à savoir $ var1 et constante à côté de cela, donc echo $ var1_costant_traling_part fonctionne pour moi
YouAreAwesome

2
Je suppose que l'on n'a besoin que d'un seul jeu pour s'échapper: echo $a\_$bferait l'affaire. Comme l'indique le commentaire de Nik O'Lai, le trait de soulignement est un personnage régulier. La gestion des espaces blancs est beaucoup plus sensible pour les chaînes, l'écho et la concaténation --- on peut utiliser \ et lire attentivement ce fil car ce problème revient de temps en temps.
XavierStuvw

16

La manière la plus simple avec des guillemets:

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

1
Trop de guillemets, à mon humble avis. var=$B$b"a"; echo Hello\ $varferait, je crois
XavierStuvw

Je suggère d'utiliser tous les guillemets, car si vous le mettez partout, vous ne pouvez pas le manquer, vous n'avez pas à réfléchir.
betontalpfa

15

Vous pouvez concaténer sans les guillemets. Voici un exemple:

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

Cette dernière instruction afficherait "OpenSystems" (sans guillemets).

Voici un exemple de script Bash:

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

1
La syntaxe du premier bloc prête à confusion. Que signifient ces signes $?
XavierStuvw

15

Même si l'opérateur + = est désormais autorisé, il a été introduit dans Bash 3.1 en 2004.

Tout script utilisant cet opérateur sur les anciennes versions de Bash échouera avec une erreur "commande introuvable" si vous êtes chanceux, ou une "erreur de syntaxe près d'un jeton inattendu".

Pour ceux qui se soucient de la compatibilité descendante, respectez les anciennes méthodes de concaténation Bash standard, comme celles mentionnées dans la réponse choisie:

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

1
Merci de l'avoir signalé, je cherchais simplement la version requise pour que cela fonctionne.
Rho Phi

14

Je préfère utiliser des accolades ${}pour développer la variable dans la chaîne:

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

Les accolades correspondent à l'utilisation continue de la chaîne:

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

Sinon, l'utilisation foo = "$fooWorld"ne fonctionnera pas.


8

Si ce que vous essayez de faire est de diviser une chaîne en plusieurs lignes, vous pouvez utiliser une barre oblique inverse:

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

Avec un espace entre les deux:

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

Celui-ci ajoute également un seul espace entre les deux:

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

Je crains que ce ne soit pas ce que l'on voulait dire
installero

7

Moyen plus sûr:

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

Les chaînes contenant des espaces peuvent faire partie de la commande, utilisez "$ XXX" et "$ {XXX}" pour éviter ces erreurs.

De plus, jetez un œil à une autre réponse concernant + =


Le point des chaînes avec un espace lu comme une commande apparaît au point de définition. Alors d=DD DDdonnerait DD: command not found--- note qui est la dernière DD plutôt d qu'on ne trouve pas. Si tous les opérandes sont correctement formatés et contiennent déjà les espaces requis, vous pouvez simplement concaténer avec s=${a}${b}${c}${d}; echo $s, avec moins de guillemets. Vous pouvez également utiliser \ (espaces blancs échappés) pour éviter ces problèmes --- d=echo\ echone lancera aucune invocation d'écho, alors que le d=echo echofera.
XavierStuvw

7

Il y a un cas particulier où vous devez faire attention:

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

Sortira "daniel"san, et non danielsan, comme vous l'auriez voulu. Dans ce cas, vous devez faire à la place:

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

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

Voici comment concaténer deux chaînes.


1
Cela fonctionne, mais cela donnera parfois des résultats imprévisibles car l'interpolation variable n'est pas protégée. Ainsi, vous ne pouvez pas compter sur ce formulaire pour tous les cas d'utilisation.
Anthony Rutledge

5

S'il s'agit de votre exemple d'ajout " World"à la chaîne d'origine, cela peut être:

#!/bin/bash

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

Le résultat:

Hello World

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

2
A également var3=$var1\ $var2le même effet
XavierStuvw

5

Des inquiétudes ont été exprimées concernant les performances, mais aucune donnée n'est proposée. Permettez-moi de suggérer un test simple.

(REMARQUE: datesur macOS n'offre pas de nanosecondes, donc cela doit être fait sur Linux.)

J'ai créé append_test.sh sur GitHub avec le contenu:

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

Les erreurs indiquent que mon Bash a atteint 335,54432 Mo avant de planter. Vous pouvez changer le code de doubler les données à ajouter une constante pour obtenir un graphique plus précis et un point de défaillance. Mais je pense que cela devrait vous donner suffisamment d'informations pour décider si vous vous souciez. Personnellement, en dessous de 100 Mo, je n'en ai pas. Votre kilométrage peut varier.


Intéressant! Considérez: 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"(Essayez ceci sur un hôte non productif !!;)
F. Hauri

4

Je voulais construire une chaîne à partir d'une liste. Je n'ai pas trouvé de réponse à cela, alors je la poste ici. Voici ce que j'ai fait:

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

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

echo ${string}

puis j'obtiens la sortie suivante:

1 2 3 4 5

4

Malgré l'opérateur spécial +=, pour la concaténation, il existe un moyen plus simple de procéder:

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

Les guillemets doubles prennent un temps de calcul supplémentaire pour l'interprétation des variables à l'intérieur. Évitez-le si possible.


3

Notez que cela ne fonctionnera pas

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

car il semble laisser tomber $ foo et vous laisse avec:

PREFIX_WORLD

mais cela fonctionnera:

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

et vous laisse avec la sortie correcte:

PREFIX_HELLO_WORLD


8
cela se produit car le trait de soulignement est le caractère valide dans les noms de variable, donc bash voit foo_ comme une variable. Lorsqu'il est nécessaire de dire à bash les limites exactes du nom var, les accolades peuvent être utilisées: PREFIX _ $ {foo} _ $ bar
Nik O'Lai

2

Voici celui via AWK :

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

1
Bien, mais je pense que je pourrais obtenir plus de précision en utilisant Python!
techno

1

Je le fais de cette façon quand c'est pratique: Utilisez une commande en ligne!

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

1
En 1ère ligne, vous pouvez supprimer une fourchette en utilisant:, date "+The current time is %a %b %d %Y +%T"au lieu de echo ...$(date). Sous bash récente, vous pouvez écrire: printf "The current time is %(%a %b %d %Y +%T)T\n" -1.
F.Hauri

1

À mon avis, la façon la plus simple de concaténer deux chaînes est d'écrire une fonction qui le fait pour vous, puis d'utiliser cette fonction.

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

J'aime un peu faire une fonction rapide.

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

echo $(combo 'foo''bar')

Encore une autre façon d'écorcher un chat. Cette fois avec des fonctions: D


Appeler une fonction, cela aussi en sous-shell, est trop exagéré pour un simple enchaînement.
codeforester

-1

Je ne connais pas encore PHP, mais cela fonctionne dans Linux Bash. Si vous ne voulez pas l'affecter à une variable, vous pouvez essayer ceci:

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

>Hello World!

Vous pouvez placer une autre variable au lieu de «Bonjour» ou «!». Vous pouvez également concaténer plus de chaînes.


2
Utiliser un sous-shell pour faire une concaténation simple est beaucoup trop cher!
codeforester
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.