Soru Bash'de dize değişkenleri nasıl birleştirilir


PHP'de, dizeler aşağıdaki gibi birlikte birleştirilir:

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

İşte, $foo "Merhaba Dünya" olur.

Bu Bash’te nasıl başarılı olur?


2102
2017-11-15 05:38


Menşei


foo="Hello"  foo=$foo" World"  echo $foo      Bu oldukça "#! / bin / sh" için çalıştı - parasrish
Eğer boşluk olmadan HelloWorld istiyorsanız ne yapmalı? - Adi


Cevaplar:


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

Genel olarak iki değişkeni birleştirmek için birbiri ardına yazabilirsiniz:

a='hello'
b='world'
c=$a$b
echo $c
> helloworld

2852
2017-11-15 05:41



Alıştırma alışkanlığını kazanmak için muhtemelen iyi $foo Çift tırnak içinde, gerçekten önemli olduğu zamanlar için. - Cascabel
Her zaman bunu yapmayı öğretiyoruz çünkü ikame gerçekleştiğinde, kabuğun boşlukları yok sayılacak, ancak çift tırnaklar bu alanları her zaman koruyacaktır. - Strawberry
İlk örneğinizde bir boşluk olmalı mı? Gibi bir şey yapmak mümkün mü foo="$fooworld"? Varsayım ... - nonsensickle
@nonsensickle Bu adında bir değişken arardı fooworld. Braces ile yapılan disambiguating, olduğu gibi foo="${foo}world"... - twalberg
@ JVE999 Evet, bu da işe yarıyor, bence bence kod açıklığı için o kadar iyi değil ... Ama bu benim tercihim olabilir ... Bunun da yapılabileceği birkaç başka yol var - nokta Değişken adın değişken olmayan isim parçalarından ayrıldığından emin olun, böylelikle doğru şekilde ayrıştırılır. - twalberg


Bash ayrıca aşağıdaki transkriptte gösterildiği gibi bir + = operatörünü destekler:

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

939
2017-11-15 08:33



Bu kabul edilen cevaptan çok daha iyi, teşekkürler! Bu soruyu daha kolay bulmak için etiket olarak "ekle" yi ekledik. - noamtm
Bu sözdizimini dışa aktarma anahtar kelimesiyle kullanabilir miyim? Örneğin. export A+="Z" ya da belki A Değişken sadece bir kez ihraç edilmek zorunda mı? - levesque
@levesque: Her ikisi de :-). Değişkenlerin yalnızca bir kez dışa aktarılması gerekir, ancak export A+=Z oldukça iyi çalışıyor. - thkala
Bu bir bashizm olduğundan, asla kullanmamanız gereken bir şey olduğunu düşünüyorum. #!/bin/sh bu yapıyı kullanan bir senaryoda. - Score_Under
Özellikle ve sadece artı eşittir operatör. Yani, Javascript'in aksine, Bash'de, echo $ A + $ B, "X Y + Z" basar. - phpguru


Önce Bash

Bu soru özellikle darbe, cevabın ilk kısmı bunu doğru şekilde yapmanın farklı yollarını sunacaktır:

+=: Değişkene ekle

Sözdizimi += farklı şekillerde kullanılabilir:

Dizeye ekle var+=...

(Çünkü ben tutumluyum, sadece iki değişken kullanacağım foo ve a ve sonra tüm cevabı aynı şekilde tekrar kullanın. ;-)

a=2
a+=4
echo $a
24

Kullanmak Yığın taşması sorusu sözdizimi,

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

iyi çalışıyor!

Bir tam sayıya ekle ((var+=...))

değişken a bir dizgidir, fakat aynı zamanda bir tamsayıdır

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

Bir diziye ekle var+=(...)

bizim a aynı zamanda sadece bir element dizisidir.

echo ${a[@]}
36

a+=(18)

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

Parantezler arasında, bir boşluk ayrılmış dizi. Dizinizdeki boşlukları içeren bir dizgi saklamak istiyorsanız, bunları içine almanız gerekir:

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

Hmm .. Bu bir hata değil, bir özellik... Bash'ı geliştirmeye çalışmak için !", yapabilirdin:

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: Kullanarak değişkenleri yeniden yapılandırın builtin komuta

printf  builtin Komut, dize formatını çizmenin güçlü bir yolunu sunar. Bu bir Bash olduğu gibi builtin, biçimlendirilmiş dize yazdırmak yerine bir değişkene göndermek için bir seçenek var stdout:

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

Yedi tane var Teller bu dizide. Böylece tam olarak yedi konumsal argüman içeren biçimlendirilmiş bir dizi oluşturabiliriz:

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

Ya da kullanabilirdik bir argüman formatı dize Gönderilen birçok argüman tekrarlanacak ...

Unutmayın ki bizim a hala bir dizi! Sadece ilk eleman değiştirildi!

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

Bash altında, endeks belirtmeden bir değişken ismine eriştiğinizde, her zaman sadece ilk öğeyi adreslersiniz!

Yani yedi alan dizimizi geri almak için, sadece 1. elemanı yeniden ayarlamamız gerekiyor:

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

Birçok bağımsız değişken içeren bir bağımsız değişken biçim dizesi:

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

Kullanmak Yığın taşması sorusu sözdizimi:

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

Nota: Kullanımı ikili alıntı içeren dizeleri işlemek için yararlı olabilir spaces, tabulations ve / veya newlines

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

Şimdi kabuk

Altında POSIX kabuk kullanamazsın bashisms, yani yok builtin  printf.

temel olarak

Ama basitçe yapabilirsin:

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

Biçimlendirilmiş, kullanarak çatallı  printf

Daha sofistike yapılar kullanmak istiyorsanız, çatal (işi yapan ve sonuca stdout):

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

Tarihsel olarak kullanabilirsiniz backticks sonucu almak için çatal:

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

Ama bunun için kolay değil yuvalama:

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

backticks ile, iç çatal ile kaçmak zorunda ters eğik çizgi:

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

807
2017-08-04 10:04



+= operatör de daha hızlı $a="$a$b" Benim testlerimde .. Hangisi mantıklı. - Matt
Bu cevap harika, ama bence eksik. var=${var}.sh Diğer cevaplardan örnek, çok kullanışlı. - geneorama
mı bash ile tek kabuk += Şebeke? Yeterince taşınabilir olup olmadığını görmek istiyorum - dashesy
@ dashesy no. Ben kesinlikle tek kabuk ile değil += operatör, ama tüm bu yollar bashisms, bu yüzden taşınabilir değil! Yanlış bash versiyonunda bile özel hatalarla karşılaşabilirsiniz! - F. Hauri


Bunu da yapabilirsin:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh

114
2017-10-28 03:09



Özel karakterler veya boşluk kullanılmazken, çift tırnak, tırnak ve kaşlı ayraçlar işe yaramaz: var=myscript;var=$var.sh;echo $var Aynı etkiler olurdu (Bu bash, dash, busybox ve diğerleri altında çalışır). - F. Hauri


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

Çıktı olacak

helloohaikthxbye

Bu yararlı      $blaohai değişken bir hataya yol açar. Veya dizelerinizde boşluk veya başka özel karakterler varsa. "${foo}" içine koyduğunuz her şeyi düzgün bir şekilde kaçar.


103
2017-07-25 15:48



Çalışmıyor. "Backupstorefolder: komut bulunamadı" bash'tan "backupstorefolder" değişkeninin adıdır. - Zian Choy
Bu, sözdizimini vurgulamaya yardımcı olur ve bazı insan belirsizliklerini ortadan kaldırır. - Ray Foss


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


35
2017-11-15 05:44



Bu kabuk betiği için en kullanışlı cevaptır. Son 30 dakikayı kendim buldum çünkü eşit işaretlerden önce ve sonra bir alanım vardı! - Stefan
foo = "$ {foo} Dünya" - XXL


Sorunu çözdüğüm yol sadece

$a$b

Örneğin,

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

hangi üretir

Hello World

Örneğin bir dizeyi başka bir dizeyle birleştirmeye çalışırsanız

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

sonra echo "$c" üretecek

Hello World

ekstra alan.

$aWorld

Hayal edemeyeceğiniz gibi çalışmıyor, ama

${a}World

üretir

HelloWorld

29
2018-03-07 16:43



... dolayısıyla ${a}\ World üretir Hello World - XavierStuvw