In PHP worden strings als volgt samengevoegd:
$foo = "Hello";
$foo .= " World";
Hier wordt $foo
“Hallo wereld”.
Hoe wordt dit bereikt in Bash?
Antwoord 1, autoriteit 100%
foo="Hello"
foo="${foo} World"
echo "${foo}"
> Hello World
In het algemeen kunt u, om twee variabelen samen te voegen, ze gewoon achter elkaar schrijven:
a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
Antwoord 2, autoriteit 29%
Bash ondersteunt ook een +=
operator zoals getoond in deze code:
A="X Y"
A+=" Z"
echo "$A"
uitvoer
X Y Z
Antwoord 3, autoriteit 24%
Bash eerst
Aangezien deze vraag specifiek voor Bashstaat, is mijn eerste deel van het antwoord zou verschillende manieren presenteren om dit goed te doen:
+=
: toevoegen aan variabele
De syntaxis +=
kan op verschillende manieren worden gebruikt:
Toevoegen aan string var+=...
(Omdat ik zuinig ben, zal ik slechts twee variabelen foo
en a
gebruiken en vervolgens dezelfde opnieuw gebruiken in het hele antwoord. 😉
a=2
a+=4
echo $a
24
De syntaxis Stack Overflow-vraaggebruiken,
foo="Hello"
foo+=" World"
echo $foo
Hello World
werkt prima!
Toevoegen aan een geheel getal ((var+=...))
variabele a
is een string, maar ook een geheel getal
echo $a
24
((a+=12))
echo $a
36
Toevoegen aan een array var+=(...)
Onze a
is ook een array van slechts één element.
echo ${a[@]}
36
a+=(18)
echo ${a[@]}
36 18
echo ${a[0]}
36
echo ${a[1]}
18
Merk op dat er tussen haakjes een door spaties gescheiden arraystaat. Als u een string met spaties in uw array wilt opslaan, moet u deze omsluiten:
a+=(one word "hello world!" )
bash: !": event not found
Hmm.. dit is geen bug, maar een functie… Om te voorkomen dat bash probeert te ontwikkelen !"
, kunt u:
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
: Reconstrueer de variabele met het ingebouwdecommando
De opdracht printf
ingebouwdegeeft een krachtige manier om tekenreeksen te tekenen. Aangezien dit een Bash ingebouwdis, is er een optie om een opgemaakte string naar een variabele te sturen in plaats van af te drukken op stdout
:
echo ${a[@]}
36 18 one word hello world! hello world! hello world!
Er zijn zeven stringsin deze array. We zouden dus een opgemaakte string kunnen bouwen die precies zeven positionele argumenten bevat:
printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'" "${a[@]}"
echo $a
36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'
Of we kunnen één tekenreeks voor argumentopmaakgebruiken die wordt herhaald als er zoveel argumenten zijn ingediend…
Merk op dat onze a
nog steeds een array is! Alleen het eerste element is gewijzigd!
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!")'
Onder bash, wanneer u een variabelenaam opent zonder index op te geven, adresseert u altijd alleen het eerste element!
Dus om onze array met zeven velden op te halen, hoeven we alleen het eerste element opnieuw in te stellen:
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!")'
Eén tekenreeks voor argumentindeling met veel argumenten doorgegeven aan:
printf -v a[0] '<%s>\n' "${a[@]}"
echo "$a"
<36>
<18>
<one>
<word>
<hello world!>
<hello world!>
<hello world!>
De syntaxis Stack Overflow-vraaggebruiken:
foo="Hello"
printf -v foo "%s World" $foo
echo $foo
Hello World
Opmerking: Het gebruik van dubbele aanhalingstekenskan handig zijn voor het manipuleren van tekenreeksen die spaces
, tabulations
en/of newlines
printf -v foo "%s World" "$foo"
Shell nu
Onder POSIXshell kon je geen bashismsgebruiken, dus er is geen ingebouwdeprintf
.
Eigenlijk
Maar je zou gewoon kunnen doen:
foo="Hello"
foo="$foo World"
echo $foo
Hello World
Geformatteerd, met behulp van gevorkteprintf
Als je meer geavanceerde constructies wilt gebruiken, moet je een forkgebruiken (nieuw onderliggend proces dat de taak maakt en het resultaat retourneert via stdout
):
foo="Hello"
foo=$(printf "%s World" "$foo")
echo $foo
Hello World
Historisch gezien zou u backtickskunnen gebruiken om het resultaat van een forkop te halen:
foo="Hello"
foo=`printf "%s World" "$foo"`
echo $foo
Hello World
Maar dit is niet gemakkelijk voor nesten:
foo="Today is: "
foo=$(printf "%s %s" "$foo" "$(date)")
echo $foo
Today is: Sun Aug 4 11:58:23 CEST 2013
met backticks moet je de binnenvorken ontwijken met backslashes:
foo="Today is: "
foo=`printf "%s %s" "$foo" "\`date\`"`
echo $foo
Today is: Sun Aug 4 11:59:10 CEST 2013
Antwoord 4, autoriteit 3%
U kunt dit ook doen:
$ var="myscript"
$ echo $var
myscript
$ var=${var}.sh
$ echo $var
myscript.sh
Antwoord 5, autoriteit 3%
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"
Zal uitvoeren
helloohaikthxbye
Dit is handig wanneer
$blaohai
leidt tot een variabele niet gevonden fout. Of als je spaties of andere speciale tekens in je strings hebt. "${foo}"
ontsnapt correct aan alles wat je erin stopt.
Antwoord 6
foo="Hello "
foo="$foo World"
Antwoord 7
Hier is een beknopte samenvatting van waar de meeste antwoorden over gaan.
Stel dat we twee variabelen hebben en $1 is ingesteld op ‘één’:
set one two
a=hello
b=world
De onderstaande tabel legt de verschillende contexten uit waarin we de waarden van a
en b
kunnen combineren om een nieuwe variabele te creëren, 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
Een paar opmerkingen:
- het plaatsen van de RHS van een opdracht tussen dubbele aanhalingstekens is over het algemeen een goede gewoonte, hoewel het in veel gevallen vrij optioneel is
+=
is vanuit prestatieoogpunt beter als een grote string in kleine stappen wordt geconstrueerd, vooral in een lus- gebruik
{}
rond variabelenamen om hun uitbreiding ondubbelzinnig te maken (zoals in rij 2 in de bovenstaande tabel). Zoals te zien is in rijen 3 en 4, is{}
niet nodig, tenzij een variabele wordt samengevoegd met een tekenreeks die begint met een teken dat een geldig eerste teken is in de naam van de shell-variabele, dat wil zeggen alfabet of onderstrepingsteken.
Zie ook:
- BashFAQ/013 – Hoe kan ik twee variabelen samenvoegen?
- Wanneer hebben we accolades rond shell-variabelen nodig?
Antwoord 8
De manier waarop ik het probleem zou oplossen is gewoon
$a$b
Bijvoorbeeld
a="Hello"
b=" World"
c=$a$b
echo "$c"
die produceert
Hello World
Als u bijvoorbeeld een tekenreeks probeert samen te voegen met een andere tekenreeks,
a="Hello"
c="$a World"
Dan echo "$c"
produceert
Hello World
met een extra ruimte.
$aWorld
werkt niet, zoals u zich mag voorstellen, maar
${a}World
produceert
HelloWorld
Antwoord 9
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
Antwoord 10
Nog een andere aanpak …
> H="Hello "
> U="$H""universe."
> echo $U
Hello universe.
… en toch nog een andere.
> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.
Antwoord 11
Als u iets als een onderstrepingsporen wilt toevoegen, gebruik dan Escape (\)
FILEPATH=/opt/myfile
Dit doet niet werk:
echo $FILEPATH_$DATEX
Dit werkt prima:
echo $FILEPATH\\_$DATEX
Antwoord 12
De eenvoudigste manier met aanhalingstekens:
B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
Antwoord 13
Zelfs als de += operator nu is toegestaan, is deze in 2004 geïntroduceerd in Bash 3.1.
Elk script dat deze operator op oudere Bash-versies gebruikt, zal mislukken met een “opdracht niet gevonden”-fout als je geluk hebt, of een “syntaxisfout bijna onverwacht token”.
Voor degenen die achterwaartse compatibiliteit belangrijk vinden, blijf bij de oudere standaard Bash-aaneenschakelingsmethoden, zoals die vermeld in het gekozen antwoord:
foo="Hello"
foo="$foo World"
echo $foo
> Hello World
Antwoord 14
U kunt samenvoegen zonder de aanhalingstekens. Hier is een voorbeeld:
$Variable1 Open
$Variable2 Systems
$Variable3 $Variable1$Variable2
$echo $Variable3
Deze laatste verklaring zou “OpenSystems” (zonder aanhalingstekens) afdrukken.
Dit is een voorbeeld van een Bash-script:
v1=hello
v2=world
v3="$v1 $v2"
echo $v3 # Output: hello world
echo "$v3" # Output: hello world
Antwoord 15
Ik gebruik liever accolades ${}
om variabele in string uit te breiden:
foo="Hello"
foo="${foo} World"
echo $foo
> Hello World
Krulhaken passen bij continu tekenreeksgebruik:
foo="Hello"
foo="${foo}World"
echo $foo
> HelloWorld
Anders werkt het gebruik van foo = "$fooWorld"
niet.
Antwoord 16
Als u probeert een string te splitsenin meerdere regels, kunt u een backslash gebruiken:
$ a="hello\
> world"
$ echo $a
helloworld
Met één spatie ertussen:
$ a="hello \
> world"
$ echo $a
hello world
Deze voegt ook maar één spatie ertussen toe:
$ a="hello \
> world"
$ echo $a
hello world
Antwoord 17
Veiligere manier:
a="AAAAAAAAAAAA"
b="BBBBBBBBBBBB"
c="CCCCCCCCCCCC"
d="DD DD"
s="${a}${b}${c}${d}"
echo "$s"
AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD
Tekenreeksen die spaties bevatten, kunnen onderdeel worden van de opdracht. Gebruik “$XXX” en “${XXX}” om deze fouten te voorkomen.
Kijk ook eens naar een ander antwoord over +=
Antwoord 18
Er is één specifiek geval waar u op moet letten:
user=daniel
cat > output.file << EOF
"$user"san
EOF
Geef "daniel"san
weer, en niet danielsan
, zoals je misschien had gewild.
In dit geval moet u in plaats daarvan doen:
user=daniel
cat > output.file << EOF
${user}san
EOF
Antwoord 19
Ondanks de speciale operator, +=
, is er voor aaneenschakeling een eenvoudigere manier:
foo='Hello'
foo=$foo' World'
echo $foo
Dubbele aanhalingstekens kosten extra rekentijd voor de interpretatie van variabelen binnenin. Vermijd het indien mogelijk.
Antwoord 20
a="Hello,"
a=$a" World!"
echo $a
Dit is hoe je aaneenschakelen twee strings.
Antwoord 21
Als het als uw voorbeeld van het toevoegen " World"
om de oorspronkelijke tekenreeks, dan kan het zijn:
#!/bin/bash
foo="Hello"
foo=$foo" World"
echo $foo
De uitvoer:
Hello World
Antwoord 22
var1='hello'
var2='world'
var3=$var1" "$var2
echo $var3
Antwoord 23
Er zijn zorgen geuit over de prestaties, maar er worden geen gegevens aangeboden. Laat me een eenvoudige test.
(NB:. date
MacOS niet bieden nanoseconden, dus dit moet worden gedaan op Linux)
ik heb gemaakt append_test.sh op GitHub met de inhoud:
#!/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
De fouten geven aan dat mijn Bash maximaal 335.54432 MBhad voordat het crashte. U kunt de codewijzigen van het verdubbelen van de gegevens naar het toevoegen van een constante om een meer gedetailleerde grafiek te krijgen en faalpunt. Maar ik denk dat dit je genoeg informatie moet geven om te beslissen of het je iets kan schelen. Persoonlijk doe ik dat niet onder de 100 MB. Uw kilometerstand kan variëren.
Antwoord 24
Ik wilde een string maken van een lijst. Ik kon daar geen antwoord op vinden, dus post ik het hier. Dit is wat ik deed:
list=(1 2 3 4 5)
string=''
for elm in "${list[@]}"; do
string="${string} ${elm}"
done
echo ${string}
en dan krijg ik de volgende uitvoer:
1 2 3 4 5
Antwoord 25
Merk op dat dit niet werkt
foo=HELLO
bar=WORLD
foobar=PREFIX_$foo_$bar
omdat het $foo lijkt te laten vallen en je achterlaat met:
PREFIX_WORLD
maar dit zal werken:
foobar=PREFIX_"$foo"_"$bar"
en je de juiste output geven:
PREFIX_HELLO_WORLD
Antwoord 26
Hier is die van AWK:
$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
Antwoord 27
Ik doe het op deze manier wanneer het mij uitkomt: gebruik een inline commando!
echo "The current time is `date`"
echo "Current User: `echo $USER`"
Antwoord 28
Naar mijn mening is de eenvoudigste manier om twee strings samen te voegen, door een functie te schrijven die dit voor u doet en die functie vervolgens te gebruiken.
function concat ()
{
prefix=$1
suffix=$2
echo "${prefix}${suffix}"
}
foo="Super"
bar="man"
concat $foo $bar # Superman
alien=$(concat $foo $bar)
echo $alien # Superman
Antwoord 29
Variabelen en arrays (geïndexeerd of associatief*) in bash zijn standaard altijd strings, maar je kunt vlaggen gebruiken om de ingebouwde declare
te gebruiken, om ze attributen te geven zoals “integer” (-i
) of “referentie”** (-n
), die de manier waarop ze zich gedragen veranderen.
Bash-rekenkunde accepteert ASCII-/tekenreeksnummers voor invoer, dus er zijn weinig redenen om het integer-kenmerk daadwerkelijk te gebruiken.
Variabele waarden mogen ook geen ASCII NULL
(dwz 8 bit nul) bevatten, omdat er gewone null-getermineerde C-strings worden gebruikt om ze te implementeren.
* Dwz een of meer sleutel + waarde-paren.
** Referentievariabelen breiden uit naar de waarde van een andere variabele, waarvan het label is toegewezen aan de referentievariabele
Een tekenreeks toevoegen:
$ foo=Hello
$ foo+=' world!'
$ echo "$foo"
Hello world!
$ num=3
$ num+=4
echo "$num"
34 # Appended string (not a sum)
Een van de weinige redenen om het integer-attribuut te gebruiken, is dat het het gedrag van de +=
toewijzingsoperator wijzigen:
$ declare -i num=3
$ num+=4
echo "$num"
7 # Sum
Merk op dat dit niet werkt voor -=
, /=
, enz. Tenzij u het binnen rekenkundige doet ((( ))
en $(( ))
), waar cijfers al hetzelfde zijn behandeld met of zonder het attribuut van de integer. Zie de sectie “Rekenkundige evaluatie” van man bash
voor een volledige lijst van die exploitanten, die hetzelfde zijn als voor c.
De +=
Opdrachtoperator kan ook worden gebruikt om nieuwe elementen toe te voegen aan een geïndexeerde array (aka “lijst”):
$ foo=(one)
$ foo+=(two)
$ printf 'Separate element: %s\n' "${foo[@]}"
Separate element: one
Separate element: two
Nog een gemeenschappelijke manier om dit te doen is om een teller te gebruiken:
$ foo[c++]=one
$ foo[c++]=two
Posix Shells DO Niet Gebruik de +=
toewijzingsoperator om strings toe te voegen, dus u moet het zo doen:
$ foo=Hello
$ foo="$foo world!"
$ echo "$foo"
Hello world!
Dit is prima in bash
ook, dus het kan worden beschouwd als een meer draagbare syntaxis.
ANTWOORD 30
Ik vind het leuk om een snelle functie te maken.
#! /bin/sh -f
function combo() {
echo $@
}
echo $(combo 'foo''bar')
Nog een andere manier om een kat te vullen. Deze keer met functies: D