So verketten Sie Zeichenfolgenvariablen in Bash

2767

In PHP werden Zeichenfolgen wie folgt miteinander verknüpft:

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

Hier $foowird "Hallo Welt".

Wie wird dies in Bash erreicht?

Erdbeere
quelle
6
foo="Hello" foo=$foo" World" echo $foo Dies funktionierte eher für "#! / bin / sh"
Parasrish
1
Was tun, wenn Sie HelloWorld ohne Speicherplatz möchten?
Adi
@ Adifoo1="World" foo2="Hello" foo3="$foo1$foo2"
GeneCode
Leerzeichen macht eine Sache in Bash)
Capibar

Antworten:

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

Um zwei Variablen zu verketten, können Sie sie im Allgemeinen einfach nacheinander schreiben:

a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
Codaddict
quelle
314
Wahrscheinlich gut, um sich daran zu gewöhnen, $foodoppelte Anführungszeichen zu setzen, für die Zeiten, in denen es wirklich wichtig ist.
Cascabel
104
Wir haben gelernt, dies immer zu tun, da Leerzeichen bei der Ersetzung von der Shell ignoriert werden, doppelte Anführungszeichen diese Leerzeichen jedoch immer schützen.
Erdbeere
62
Muss in Ihrem ersten Beispiel ein Leerzeichen sein? Ist es möglich so etwas zu tun foo="$fooworld"? Ich würde nicht annehmen ...
unsinnig
341
@nonsensickle Das würde nach einer Variablen namens suchen fooworld. Disambiguierung, dass mit Klammern gemacht wird, wie in foo="${foo}world"...
Twalberg
4
@ JVE999 Ja, das funktioniert auch, obwohl es meiner Meinung nach nicht ganz so gut für die Klarheit des Codes ist ... Aber das mag nur meine Präferenz sein ... Es gibt noch ein paar andere Möglichkeiten, wie es gemacht werden kann - der Punkt ist Stellen Sie sicher, dass der Variablenname von den Teilen ohne Variablennamen getrennt ist, damit er korrekt analysiert wird.
Twalberg
1127

Bash unterstützt auch einen +=Operator, wie in diesem Code gezeigt:

$ A="X Y"
$ A+=" Z"
$ echo "$A"
X Y Z
thkala
quelle
2
Kann ich diese Syntax mit dem Schlüsselwort export verwenden? zB export A+="Z"oder muss die AVariable nur einmal exportiert werden?
Levesque
3
@levesque: Beide :-). Variablen müssen nur einmal exportiert werden, export A+=Zfunktionieren aber auch ganz gut.
Thkala
38
Da dies ein Bashismus ist, ist es meiner Meinung nach erwähnenswert, dass Sie ihn niemals #!/bin/shin einem Skript verwenden sollten, das diese Konstruktion verwendet.
Score_Under
2
Es ist spezifisch und nur ein Plus-Gleichheitsoperator. Das heißt, im Gegensatz zu Javascript druckt Echo $ A + $ B in Bash "X Y + Z"
phpguru
6
Ein Bashism ist eine Shell-Funktion, die nur in bashund einigen anderen fortgeschritteneren Shells unterstützt wird. Es funktioniert nicht unter busybox shoder dash(was /bin/shin vielen Distributionen der Fall ist) oder bestimmten anderen Shells wie den /bin/shauf FreeBSD bereitgestellten.
Score_Under
960

Bash zuerst

Da diese Frage speziell für Bash steht , würde mein erster Teil der Antwort verschiedene Möglichkeiten aufzeigen, dies richtig zu machen:

+=: An Variable anhängen

Die Syntax +=kann auf verschiedene Arten verwendet werden:

An String anhängen var+=...

(Weil ich sparsam bin, werde ich nur zwei Variablen verwenden foound adann wieder verwenden das gleiche in der ganzen Antwort. ;-)

a=2
a+=4
echo $a
24

Verwenden der Stack Overflow- Fragensyntax:

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

funktioniert gut!

An eine Ganzzahl anhängen ((var+=...))

Variable aist eine Zeichenfolge, aber auch eine Ganzzahl

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

An ein Array anhängen var+=(...)

Unser aist auch eine Reihe von nur einem Element.

echo ${a[@]}
36

a+=(18)

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

Beachten Sie, dass zwischen Klammern ein durch Leerzeichen getrenntes Array steht . Wenn Sie eine Zeichenfolge mit Leerzeichen in Ihrem Array speichern möchten, müssen Sie diese einschließen:

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

Hmm .. das ist kein Fehler, sondern eine Funktion ... Um zu verhindern, dass Bash versucht, sich zu entwickeln !", könnten Sie:

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: Variable mit dem eingebauten Befehl neu erstellen

Der printf eingebaute Befehl bietet eine leistungsstarke Möglichkeit zum Zeichnen des Zeichenfolgenformats. Da dies ein eingebauter Bash ist , gibt es eine Option zum Senden einer formatierten Zeichenfolge an eine Variable, anstatt auf Folgendes zu drucken stdout:

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

Dieses Array enthält sieben Zeichenfolgen . Wir könnten also eine formatierte Zeichenfolge erstellen, die genau sieben Positionsargumente enthält:

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

Oder wir könnten eine Zeichenfolge im Argumentformat verwenden, die wiederholt wird, sobald viele Argumente eingereicht wurden ...

Beachten Sie, dass unser aArray immer noch ist! Nur das erste Element wird geändert!

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

Wenn Sie unter bash auf einen Variablennamen zugreifen, ohne einen Index anzugeben, adressieren Sie immer nur das erste Element!

Um unser Array mit sieben Feldern abzurufen, müssen wir nur das erste Element zurücksetzen:

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

Eine Zeichenfolge im Argumentformat mit vielen Argumenten, die übergeben werden an:

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

Verwenden der Stack Overflow- Fragensyntax:

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

Hinweis: Die Verwendung von doppelten Anführungszeichen kann nützlich sein, um Zeichenfolgen zu bearbeiten spaces, die tabulationsund / oder enthaltennewlines

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

Shell jetzt

Unter der POSIX- Shell konnten Sie keine Bashismen verwenden , daher ist keine integrierte Funktion vorhanden printf .

Grundsätzlich

Aber Sie könnten einfach tun:

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

Formatiert mit Gabel printf

Wenn Sie komplexere Konstruktionen verwenden möchten, müssen Sie einen Fork verwenden (neuer untergeordneter Prozess, der den Job erstellt und das Ergebnis über zurückgibt stdout):

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

In der Vergangenheit konnten Sie Backticks zum Abrufen des Ergebnisses einer Gabelung verwenden :

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

Dies ist jedoch nicht einfach zum Verschachteln :

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

Mit Backticks müssen Sie den inneren Gabeln mit Backslashes entkommen :

foo="Today is: "
foo=`printf "%s %s" "$foo" "\`date\`"`
echo $foo
Today is: Sun Aug 4 11:59:10 CEST 2013
F. Hauri
quelle
4
Der +=Bediener ist auch viel schneller als $a="$a$b"in meinen Tests. Was Sinn macht.
Matt
7
Diese Antwort ist fantastisch, aber ich denke, es fehlt das var=${var}.shBeispiel in anderen Antworten, was sehr nützlich ist.
Genorama
1
Ist bashdie einzige Shell mit +=Operator? Ich möchte sehen, ob es tragbar genug ist
schneidiger
1
@dashesy nein. Ich bin sicherlich nicht die einzige Shell mit +=Operator, aber all diese Möglichkeiten sind Bashismen , also nicht tragbar! Sogar Sie könnten im Falle einer falschen Bash-Version auf einen besonderen Fehler stoßen!
F. Hauri
134

Sie können dies auch tun:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh
userend
quelle
4
Während weder Sonderzeichen noch Leerzeichen verwendet werden, sind doppelte Anführungszeichen, Anführungszeichen und geschweifte Klammern nutzlos: var=myscript;var=$var.sh;echo $varDies hätte die gleichen Auswirkungen (dies funktioniert unter Bash, Dash, Busybox und anderen).
F. Hauri
@ F.Hauri, danke, dass du darauf hingewiesen hast. Aber wenn Sie eine Nummer anhängen würden, würde es nicht funktionieren: zB echo $var2produziert nichtmyscript2
Pynchia
@Pynchia Dies funktioniert, weil der Punkt .im Variablennamen unzulässig ist. Wenn sonst echo ${var}2oder siehe meine Antwort
F. Hauri
119
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"

Wird ausgegeben

helloohaikthxbye

Dies ist nützlich, wenn $blaohai ein Fehler mit einer Variablen nicht gefunden wird. Oder wenn Sie Leerzeichen oder andere Sonderzeichen in Ihren Zeichenfolgen haben. "${foo}"entgeht alles, was Sie hineingesteckt haben.

Orkoden
quelle
3
Funktioniert nicht Ich erhalte "backupstorefolder: Befehl nicht gefunden" von bash, wobei "backupstorefolder" der Name einer Variablen ist.
Zian Choy
7
Dies hilft bei der Hervorhebung der Syntax erheblich und beseitigt einige menschliche Unklarheiten.
Ray Foss
44
foo="Hello "
foo="$foo World"

     

vinothkr
quelle
10
Dies ist die nützlichste Antwort für Shell-Skripte. Ich habe mich in den letzten 30 Minuten wiedergefunden, weil ich vor und nach dem Gleichheitszeichen ein Leerzeichen hatte !!
Stefan
8
foo = "$ {foo} World"
XXL
@XXL Ich würde sicherlich lieber Klammern verwenden, um den Namen von var zu kapseln. Sehr zu empfehlen
Sergio A.
33

Die Art und Weise, wie ich das Problem lösen würde, ist gerecht

$a$b

Zum Beispiel,

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

was produziert

Hello World

Wenn Sie versuchen, eine Zeichenfolge mit einer anderen Zeichenfolge zu verketten, z.

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

dann echo "$c"wird produzieren

Hello World

mit einem zusätzlichen Platz.

$aWorld

funktioniert nicht, wie Sie sich vorstellen können, aber

${a}World

produziert

HelloWorld
Chris Smith
quelle
1
... daher ${a}\ WorldproduziertHello World
XavierStuvw
Das überrascht mich; Ich hätte hier erwartet c=$a$b, dasselbe zu tun wie c=$a World(was versuchen würde, Worldals Befehl ausgeführt zu werden). Ich denke, das bedeutet, dass die Zuweisung analysiert wird, bevor die Variablen erweitert werden.
mwfearnley
30

Hier ist eine kurze Zusammenfassung dessen, worüber die meisten Antworten sprechen.

Nehmen wir an, wir haben zwei Variablen und $ 1 wird auf 'eins' gesetzt:

set one two
a=hello
b=world

In der folgenden Tabelle werden die verschiedenen Kontexte erläutert, in denen wir die Werte von kombinieren aund beine neue Variable erstellen können 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

Ein paar Anmerkungen:

  • Das Einfügen der rechten Seite einer Aufgabe in doppelte Anführungszeichen ist im Allgemeinen eine gute Praxis, obwohl dies in vielen Fällen recht optional ist
  • += ist vom Standpunkt der Leistung aus besser, wenn eine große Zeichenfolge in kleinen Schritten erstellt wird, insbesondere in einer Schleife
  • Verwenden Sie {}um Variablennamen herum, um deren Erweiterung zu unterscheiden (wie in Zeile 2 in der obigen Tabelle). Wie in den Zeilen 3 und 4 zu sehen ist, ist dies nicht erforderlich, es sei {}denn, eine Variable wird mit einer Zeichenfolge verknüpft, die mit einem Zeichen beginnt, das ein gültiges erstes Zeichen im Namen der Shell-Variablen ist, dh Alphabet oder Unterstrich.

Siehe auch:

Codeforester
quelle
2
Wenn Sie über die Leistung besorgt sind, finden Sie eine Analyse in meiner Antwort stackoverflow.com/a/47878161/117471
Bruno Bronosky
29
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
bcosca
quelle
20

Noch ein Ansatz ...

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

... und noch eine.

> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.
Akseli Palén
quelle
1
Das habe ich getan und fand es so einfach und unkompliziert als die anderen Antworten. Gibt es einen Grund, warum niemand in den Antworten mit den meisten Stimmen auf diese Option hingewiesen hat?
Quimnuss
1
@quimnuss Die Tatsache, dass die Zeichenfolgen nicht mit den in der OP-Frage verwendeten übereinstimmen, könnte ein guter Grund sein.
Jlliagre
20

Wenn Sie so etwas wie einen Unterstrich anhängen möchten, verwenden Sie Escape (\).

FILEPATH=/opt/myfile

Das funktioniert nicht :

echo $FILEPATH_$DATEX

Das funktioniert gut:

echo $FILEPATH\\_$DATEX
user2800471
quelle
11
Oder alternativ $ {FILEPATH} _ $ DATEX. Hier werden {} verwendet, um die Grenzen des Variablennamens anzugeben. Dies ist angemessen, da der Unterstrich ein legales Zeichen in Variablennamen ist, sodass in Ihrem Snippet-Bash tatsächlich versucht wird, FILEPATH_ aufzulösen, nicht nur $ FILEPATH
Nik O'Lai
1
Für mich hatte ich eine Variable, dh $ var1 und eine Konstante daneben, also funktioniert echo $ var1_costant_traling_part für mich
YouAreAwesome
2
Ich denke, man braucht nur ein Spiel, um zu entkommen: echo $a\_$bwürde tun. Wie im Kommentar von Nik O'Lai angedeutet, ist der Unterstrich ein regulärer Charakter. Der Umgang mit Leerzeichen ist viel empfindlicher für Zeichenfolgen, Echo und Verkettung - man kann \ diesen Thread gründlich verwenden und lesen, da dieses Problem hin und wieder auftritt.
XavierStuvw
16

Der einfachste Weg mit Anführungszeichen:

B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
Feindealpfa
quelle
1
Zu viele Anführungszeichen, IMHO. var=$B$b"a"; echo Hello\ $varwürde tun, ich glaube
XavierStuvw
Ich schlage vor, alle Anführungszeichen zu verwenden, denn wenn Sie es überall platzieren, was Sie nicht verpassen dürfen, müssen Sie nicht nachdenken.
Feindalpfa
15

Sie können ohne Anführungszeichen verketten. Hier ist ein Beispiel:

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

Diese letzte Anweisung würde "OpenSystems" (ohne Anführungszeichen) drucken.

Dies ist ein Beispiel für ein Bash-Skript:

v1=hello
v2=world
v3="$v1       $v2"
echo $v3            # Output: hello world
echo "$v3"          # Output: hello       world
Mariana weicher
quelle
1
Die Syntax des ersten Blocks ist verwirrend. Was bedeuten diese $ -Zeichen?
XavierStuvw
15

Auch wenn der Operator + = jetzt zulässig ist, wurde er 2004 in Bash 3.1 eingeführt .

Jedes Skript, das diesen Operator in älteren Bash-Versionen verwendet, schlägt mit dem Fehler "Befehl nicht gefunden" fehl, wenn Sie Glück haben, oder mit einem "Syntaxfehler in der Nähe eines unerwarteten Tokens".

Wenn Sie sich für die Abwärtskompatibilität interessieren, sollten Sie sich an die älteren Standard-Bash-Verkettungsmethoden halten, wie sie in der ausgewählten Antwort erwähnt werden:

foo="Hello"
foo="$foo World"
echo $foo
> Hello World
Louis-Félix
quelle
1
Vielen Dank für den Hinweis, ich habe nur gesucht, welche Version erforderlich ist, damit dies funktioniert.
Rho Phi
14

Ich bevorzuge geschweifte Klammern ${}zum Erweitern der Variablen in der Zeichenfolge:

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

Geschweifte Klammern passen zur kontinuierlichen Verwendung von Zeichenfolgen:

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

Andernfalls foo = "$fooWorld"funktioniert die Verwendung nicht.

Nick Tsai
quelle
8

Wenn Sie versuchen, eine Zeichenfolge in mehrere Zeilen aufzuteilen , können Sie einen Backslash verwenden:

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

Mit einem Leerzeichen dazwischen:

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

Dieser fügt auch nur ein Leerzeichen dazwischen hinzu:

$ a="hello \
>      world"
$ echo $a
hello world
jcarballo
quelle
Ich fürchte, das ist nicht gemeint
Installero
7

Sicherer Weg:

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

Zeichenfolgen, die Leerzeichen enthalten, können Teil des Befehls werden. Verwenden Sie "$ XXX" und "$ {XXX}", um diese Fehler zu vermeiden.

Schauen Sie sich auch eine andere Antwort zu + = an

Bohdan
quelle
Der Punkt der Zeichenfolgen mit einem Leerzeichen, das als Befehl gelesen wird, wird am Definitionspunkt angezeigt. Also d=DD DDwürde geben DD: command not found--- beachten Sie, dass dies die letzte DD ist, eher d, die nicht gefunden wird. Wenn alle Operanden richtig formatiert sind und bereits die erforderlichen Leerzeichen enthalten, können Sie einfach s=${a}${b}${c}${d}; echo $smit weniger Anführungszeichen verketten . Sie können auch \ (maskiertes Leerzeichen) verwenden, um diese Probleme zu vermeiden. d=echo\ echoWird keinen Echoaufruf starten, wohingegen dies der d=echo echoFall ist.
XavierStuvw
7

Es gibt einen besonderen Fall, in dem Sie aufpassen sollten:

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

Wird ausgegeben "daniel"sanund nicht danielsan, wie Sie vielleicht wollten. In diesem Fall sollten Sie stattdessen Folgendes tun:

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

So verketten Sie zwei Zeichenfolgen.

CodeNinjaPI
quelle
1
Dies funktioniert, führt jedoch manchmal zu unvorhersehbaren Ergebnissen, da die Variableninterpolation nicht geschützt ist. Daher können Sie sich nicht für alle Anwendungsfälle auf dieses Formular verlassen.
Anthony Rutledge
5

Wenn dies Ihr Beispiel für das Hinzufügen " World"zur ursprünglichen Zeichenfolge ist, kann es sein:

#!/bin/bash

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

Die Ausgabe:

Hello World
Unpolarität
quelle
5
var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3
Hari
quelle
2
var3=$var1\ $var2
Hat
5

Es gibt Bedenken hinsichtlich der Leistung, es werden jedoch keine Daten angeboten. Lassen Sie mich einen einfachen Test vorschlagen.

(HINWEIS: Unter datemacOS werden keine Nanosekunden angeboten, daher muss dies unter Linux erfolgen.)

Ich habe append_test.sh auf GitHub mit dem Inhalt erstellt:

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

Die Fehler zeigen an, dass mein Bash bis zu 335.54432 MB groß war, bevor er abstürzte. Sie können den Code von der Verdoppelung der Daten zum Anhängen einer Konstante ändern , um ein detaillierteres Diagramm und einen Fehlerpunkt zu erhalten. Aber ich denke, dies sollte Ihnen genügend Informationen geben, um zu entscheiden, ob Sie sich interessieren. Persönlich unter 100 MB tue ich das nicht. Ihr Kilometerstand kann variieren.

Bruno Bronosky
quelle
Interessant! Bedenken Sie: 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"(Versuchen Sie dies auf einem nicht produktiven Host !!;)
F. Hauri
4

Ich wollte einen String aus einer Liste erstellen. Konnte keine Antwort darauf finden, also poste ich sie hier. Folgendes habe ich getan:

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

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

echo ${string}

und dann bekomme ich folgende ausgabe:

1 2 3 4 5
simibac
quelle
4

Trotz des speziellen Operators gibt es +=für die Verkettung einen einfacheren Weg:

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

Doppelte Anführungszeichen benötigen eine zusätzliche Berechnungszeit für die Interpretation der darin enthaltenen Variablen. Vermeiden Sie es wenn möglich.

Tiys
quelle
3

Beachten Sie, dass dies nicht funktioniert

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

wie es scheint, $ foo fallen zu lassen und lässt Sie mit:

PREFIX_WORLD

aber das wird funktionieren:

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

und lassen Sie mit der richtigen Ausgabe:

PREFIX_HELLO_WORLD

Dss
quelle
8
Dies geschieht, weil der Unterstrich das gültige Zeichen in Variablennamen ist, sodass bash foo_ als Variable sieht. Wenn es notwendig ist, bash die genauen Grenzen des Variablennamens mitzuteilen, können die geschweiften Klammern verwendet werden: PREFIX _ $ {foo} _ $ bar
Nik O'Lai
2

Hier ist der durch AWK :

$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
Avinash Raj
quelle
1
Schön, aber ich denke, ich könnte mit Python mehr Präzision erzielen!
Techno
1

Ich mache es so, wenn es Ihnen passt: Verwenden Sie einen Inline-Befehl!

echo "The current time is `date`"
echo "Current User: `echo $USER`"
Marty
quelle
1
In der ersten Zeile können Sie eine Gabel fallen lassen, indem Sie: date "+The current time is %a %b %d %Y +%T"anstelle von verwenden echo ...$(date). Unter der letzten Bash könnten Sie schreiben : printf "The current time is %(%a %b %d %Y +%T)T\n" -1.
F. Hauri
1

Meiner Meinung nach besteht der einfachste Weg, zwei Zeichenfolgen zu verketten, darin, eine Funktion zu schreiben, die dies für Sie erledigt, und diese Funktion dann zu verwenden.

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
quelle
-1

Ich mache gerne eine schnelle Funktion.

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

echo $(combo 'foo''bar')

Noch eine andere Art, eine Katze zu häuten. Diesmal mit Funktionen: D.

CommaToast
quelle
Das Aufrufen einer Funktion, auch in einer Subshell, ist für einen einfachen Concat zu viel Overkill.
Codeforester
-1

Ich weiß noch nichts über PHP, aber das funktioniert unter Linux Bash. Wenn Sie die Variable nicht beeinflussen möchten, können Sie Folgendes versuchen:

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

>Hello World!

Sie können anstelle von "Hallo" oder "!" Eine andere Variable einfügen. Sie können auch mehr Zeichenfolgen verketten.

Ayman Boubleh
quelle
2
Die Verwendung einer Subshell für eine einfache Verkettung ist viel zu teuer!
Codeforester