Cara menggabungkan variabel string di Bash

2768

Dalam PHP, string digabungkan bersama sebagai berikut:

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

Sini, $foo menjadi "Hello World".

Bagaimana ini bisa dilakukan di Bash?

Stroberi
sumber
6
foo="Hello" foo=$foo" World" echo $foo ini agak berhasil untuk "#! / bin / sh"
parasrish
1
Apa yang harus dilakukan jika Anda ingin HelloWorld tanpa ruang?
Adi
@Adifoo1="World" foo2="Hello" foo3="$foo1$foo2"
GeneCode
spasi melakukan masalah dalam bash)
Capibar

Jawaban:

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

Secara umum untuk menggabungkan dua variabel, Anda cukup menuliskannya satu per satu:

a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
codaddict
sumber
314
Mungkin bagus untuk membiasakan diri memasukkan $footanda kutip ganda, untuk saat-saat ketika itu benar-benar penting.
Cascabel
104
Kami diajarkan untuk selalu melakukan itu karena ketika pergantian berlangsung, ruang akan diabaikan oleh shell, tetapi tanda kutip ganda akan selalu melindungi ruang tersebut.
Strawberry
62
Apakah harus ada spasi dalam contoh pertama Anda? Apakah mungkin untuk melakukan sesuatu seperti itu foo="$fooworld"? Saya akan berasumsi tidak ...
nonsensickle
341
@nonsensickle Itu akan mencari variabel bernama fooworld. Mengacaukan yang dilakukan dengan kawat gigi, seperti pada foo="${foo}world"...
twalberg
4
@ JVE999 Ya, itu bekerja juga, meskipun menurut saya itu tidak cukup baik untuk kejelasan kode ... Tapi itu mungkin hanya preferensi saya ... Ada beberapa cara lain yang dapat dilakukan juga - intinya adalah pastikan nama variabel dipisahkan dari bagian-bagian yang tidak-variabel-nama sehingga mem-parsing dengan benar.
twalberg
1128

Bash juga mendukung +=operator seperti yang ditunjukkan dalam kode ini:

$ A="X Y"
$ A+=" Z"
$ echo "$A"
X Y Z
thkala
sumber
2
Bisakah saya menggunakan sintaks ini dengan kata kunci ekspor? misalnya export A+="Z"atau mungkin Avariabel hanya perlu diekspor sekali?
levesque
3
@levesque: Keduanya :-). Variabel hanya perlu diekspor sekali, tetapi export A+=Zberfungsi dengan cukup baik.
thkala
38
Karena ini adalah bashism, saya pikir patut disebutkan bahwa Anda tidak boleh menggunakan #!/bin/shskrip menggunakan konstruksi ini.
Score_Under
2
Ini khusus dan hanya operator plus-sama. Artinya, tidak seperti Javascript, dalam Bash, gema $ A + $ B mencetak "X Y + Z"
phpguru
6
Bashism adalah fitur shell yang hanya didukung bashdan beberapa shell yang lebih canggih lainnya. Ini tidak akan berfungsi di bawah busybox shatau dash(yang ada /bin/shdi banyak distro), atau shell lain seperti yang /bin/shdisediakan di FreeBSD.
Score_Under
960

Bash dulu

Karena pertanyaan ini khusus untuk Bash , bagian pertama dari jawaban saya akan menyajikan berbagai cara untuk melakukan ini dengan benar:

+=: Tambahkan ke variabel

Sintaks +=dapat digunakan dengan berbagai cara:

Tambahkan ke string var+=...

(Karena saya hemat, saya hanya akan menggunakan dua variabel foodan akemudian kembali menggunakan yang sama di seluruh jawaban. ;-)

a=2
a+=4
echo $a
24

Menggunakan sintaks pertanyaan Stack Overflow ,

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

bekerja dengan baik!

Tambahkan ke bilangan bulat ((var+=...))

variabel aadalah string, tetapi juga bilangan bulat

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

Tambahkan ke array var+=(...)

Kami ajuga merupakan array dari hanya satu elemen.

echo ${a[@]}
36

a+=(18)

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

Perhatikan bahwa di antara tanda kurung, ada array yang dipisahkan spasi . Jika Anda ingin menyimpan string yang berisi spasi di array Anda, Anda harus melampirkannya:

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

Hmm .. ini bukan bug, tetapi fitur ... Untuk mencegah bash mencoba dikembangkan !", Anda dapat:

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: Membangun ulang variabel menggunakan builtin perintah

The printf builtin perintah memberikan cara yang ampuh untuk menggambar format string. Karena ini adalah Bash bawaan , ada opsi untuk mengirim string yang diformat ke variabel alih-alih mencetak stdout:

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

Ada tujuh string dalam array ini. Jadi kita bisa membangun string yang diformat yang mengandung tujuh argumen posisi:

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

Atau kita bisa menggunakan satu string format argumen yang akan diulang karena banyak argumen yang diajukan ...

Perhatikan bahwa kami amasih berupa array! Hanya elemen pertama yang diubah!

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

Di bawah bash, ketika Anda mengakses nama variabel tanpa menentukan indeks, Anda selalu membahas elemen pertama saja!

Jadi untuk mengambil tujuh array bidang, kita hanya perlu mengatur ulang elemen 1:

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

Satu string format argumen dengan banyak argumen diteruskan ke:

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

Menggunakan sintaks pertanyaan Stack Overflow :

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

Catatan: Penggunaan tanda kutip ganda mungkin berguna untuk memanipulasi string yang berisi spaces, tabulationsdan / ataunewlines

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

Shell sekarang

Di bawah shell POSIX , Anda tidak dapat menggunakan bashism , jadi tidak ada builtin printf .

Pada dasarnya

Tapi Anda bisa melakukannya:

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

Diformat, menggunakan forked printf

Jika Anda ingin menggunakan konstruksi yang lebih canggih, Anda harus menggunakan garpu (proses anak baru yang menghasilkan pekerjaan dan mengembalikan hasilnya melalui stdout):

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

Secara historis, Anda bisa menggunakan backtick untuk mengambil hasil dari fork :

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

Tapi ini tidak mudah untuk bersarang :

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

dengan backticks, Anda harus melarikan diri dari garpu dalam dengan garis miring terbalik :

foo="Today is: "
foo=`printf "%s %s" "$foo" "\`date\`"`
echo $foo
Today is: Sun Aug 4 11:59:10 CEST 2013
F. Hauri
sumber
4
The +=Operator juga jauh lebih cepat daripada $a="$a$b"di tes saya .. Yang masuk akal.
Matt
7
Jawaban ini luar biasa, tetapi saya pikir itu kehilangan var=${var}.shcontoh dari jawaban lain, yang sangat berguna.
geneorama
1
Apakah bashsatu-satunya shell dengan +=operator? Saya ingin melihat apakah ini cukup portabel
dashesy
1
@ bulu mata tidak. Saya jelas bukan satu-satunya shell dengan +=operator, tetapi semua cara ini adalah bashism , jadi tidak portabel! Bahkan Anda dapat menemukan bug khusus jika versi bash salah!
F. Hauri
134

Anda juga dapat melakukan ini:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh
userend
sumber
4
Meskipun tidak ada karakter khusus, spasi tidak digunakan, tanda kutip ganda, tanda kutip dan kurung keriting tidak berguna: var=myscript;var=$var.sh;echo $varakan memiliki efek yang sama (Ini bekerja di bawah bash, tanda hubung, kotak sibuk dan lain-lain).
F. Hauri
@ F. Hauri terima kasih telah menunjukkannya. Tetapi jika Anda menambahkan nomor, itu tidak akan berfungsi: misalnya echo $var2tidak menghasilkanmyscript2
Pynchia
@Pynchia Ini berfungsi karena titik .ilegal pada nama variabel. Jika lain echo ${var}2atau lihat jawaban saya
F. Hauri
119
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"

Akan menghasilkan

helloohaikthxbye

Ini berguna ketika $blaohai mengarah ke variabel tidak ditemukan kesalahan. Atau jika Anda memiliki spasi atau karakter khusus lainnya di string Anda. "${foo}"benar lolos apa pun yang Anda masukkan ke dalamnya.

orkoden
sumber
3
Tidak bekerja Saya mendapatkan "backupstorefolder: perintah tidak ditemukan" dari bash di mana "backupstorefolder" adalah nama variabel.
Zian Choy
7
Ini membantu penyorotan sintaks sedikit, dan menghilangkan beberapa ambiguitas manusia.
Ray Foss
44
foo="Hello "
foo="$foo World"

     

vinothkr
sumber
10
Ini adalah jawaban yang paling berguna untuk skrip shell. Saya telah menemukan diri saya 30 menit terakhir karena saya memiliki ruang sebelum dan sesudah tanda sama !!
Stefan
8
foo = "$ {foo} Dunia"
XXL
@XXL pasti saya lebih suka menggunakan tanda kurung untuk merangkum nama var. Sangat direkomendasikan
Sergio A.
33

Cara saya memecahkan masalah itu adil

$a$b

Sebagai contoh,

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

yang menghasilkan

Hello World

Jika Anda mencoba menggabungkan string dengan string lain, misalnya,

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

maka echo "$c"akan menghasilkan

Hello World

dengan ruang ekstra.

$aWorld

tidak bekerja, seperti yang Anda bayangkan, tetapi

${a}World

menghasilkan

HelloWorld
Chris Smith
sumber
1
... karenanya ${a}\ WorldmenghasilkanHello World
XavierStuvw
Ini mengejutkan saya; Saya akan berharap di c=$a$bsini untuk melakukan hal yang sama c=$a World(yang akan mencoba dijalankan Worldsebagai perintah). Saya kira itu berarti tugas diuraikan sebelum variabel diperluas ..
mwfearnley
31

Berikut ini ringkasan singkat dari apa yang dibicarakan oleh sebagian besar jawaban.

Katakanlah kita memiliki dua variabel dan $ 1 diatur ke 'satu':

set one two
a=hello
b=world

Tabel di bawah ini menjelaskan berbagai konteks di mana kita dapat menggabungkan nilai adan buntuk membuat variabel baru 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

Beberapa catatan:

  • melampirkan RHS suatu tugas dalam tanda kutip ganda biasanya merupakan praktik yang baik, meskipun dalam banyak kasus cukup opsional
  • += lebih baik dari sudut pandang kinerja jika string besar sedang dibangun dalam peningkatan kecil, terutama dalam satu lingkaran
  • gunakan {}sekitar nama variabel untuk mendisambiguasikan ekspansi mereka (seperti pada baris 2 pada tabel di atas). Seperti terlihat pada baris 3 dan 4, tidak perlu {}kecuali variabel sedang digabungkan dengan string yang dimulai dengan karakter yang merupakan karakter pertama yang valid dalam nama variabel shell, yaitu alfabet atau garis bawah.

Lihat juga:

codeforester
sumber
2
Jika Anda mengkhawatirkan kinerja, lihat analisis dalam jawaban saya stackoverflow.com/a/47878161/117471
Bruno Bronosky
29
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
bcosca
sumber
20

Namun pendekatan lain ...

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

... dan satu lagi.

> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.
Akseli Palén
sumber
1
Itulah yang saya lakukan, dan saya menemukan itu sangat sederhana dan mudah daripada jawaban lainnya. Apakah ada alasan mengapa tidak ada orang di jawaban yang paling banyak memilih opsi ini?
quimnuss
1
@quimnuss Fakta bahwa string tidak cocok dengan yang digunakan dalam pertanyaan OP mungkin menjadi alasan yang bagus.
jlliagre
20

Jika Anda ingin menambahkan sesuatu seperti garis bawah, gunakan escape (\)

FILEPATH=/opt/myfile

Ini tidak berfungsi:

echo $FILEPATH_$DATEX

Ini berfungsi dengan baik:

echo $FILEPATH\\_$DATEX
pengguna2800471
sumber
11
Atau sebagai alternatif, $ {FILEPATH} _ $ DATEX. Di sini {} digunakan untuk menunjukkan batas-batas nama variabel. Ini tepat karena garis bawah adalah karakter hukum dalam nama variabel, jadi di bash cuplikan Anda sebenarnya mencoba menyelesaikan FILEPATH_, bukan hanya $ FILEPATH
Nik O'Lai
1
untuk saya, saya punya satu variabel yaitu $ var1 dan konstan di sebelahnya, jadi echo $ var1_costant_traling_part bekerja untuk saya
YouAreAwesome
2
Saya kira orang hanya perlu satu serangan balasan untuk melarikan diri: echo $a\_$bakan dilakukan. Seperti yang diisyaratkan dalam komentar Nik O'Lai, garis bawah adalah karakter biasa. Penanganan ruang putih jauh lebih sensitif untuk string, gema dan rangkaian --- seseorang dapat menggunakan \ dan membaca utas ini secara menyeluruh karena masalah ini muncul kembali sekarang dan kemudian.
XavierStuvw
16

Cara paling sederhana dengan tanda kutip:

B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
antara horizontal
sumber
1
Terlalu banyak tanda kutip, IMHO. var=$B$b"a"; echo Hello\ $varakan melakukan, saya percaya
XavierStuvw
Saya sarankan untuk menggunakan semua tanda kutip, karena jika Anda meletakkannya di mana-mana Anda tidak boleh ketinggalan, Anda tidak perlu berpikir.
betontalpfa
15

Anda dapat menggabungkan tanpa tanda kutip. Berikut ini sebuah contoh:

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

Pernyataan terakhir ini akan mencetak "OpenSystems" (tanpa tanda kutip).

Ini adalah contoh skrip Bash:

v1=hello
v2=world
v3="$v1       $v2"
echo $v3            # Output: hello world
echo "$v3"          # Output: hello       world
mariana lebih lembut
sumber
1
Sintaks dari blok pertama membingungkan. Apa arti $ tanda ini?
XavierStuvw
15

Bahkan jika operator + = sekarang diizinkan, ia telah diperkenalkan di Bash 3.1 pada tahun 2004.

Setiap skrip yang menggunakan operator ini pada versi Bash yang lebih lama akan gagal dengan kesalahan "perintah tidak ditemukan" jika Anda beruntung, atau "kesalahan sintaksis dekat token yang tidak terduga".

Bagi mereka yang peduli tentang kompatibilitas ke belakang, tetap menggunakan metode penggabungan Bash standar yang lebih lama, seperti yang disebutkan dalam jawaban yang dipilih:

foo="Hello"
foo="$foo World"
echo $foo
> Hello World
Louis-Félix
sumber
1
Terima kasih telah menunjukkan ini, saya hanya mencari versi mana yang diperlukan agar ini berfungsi.
Rho Phi
14

Saya lebih suka menggunakan kurung keriting ${}untuk memperluas variabel dalam string:

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

Kurung keriting akan cocok dengan penggunaan string Berkelanjutan:

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

Kalau tidak menggunakan foo = "$fooWorld"tidak akan berfungsi.

Nick Tsai
sumber
8

Jika yang ingin Anda lakukan adalah membagi string menjadi beberapa baris, Anda dapat menggunakan garis miring terbalik:

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

Dengan satu ruang di antaranya:

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

Yang ini juga menambahkan hanya satu ruang di antara:

$ a="hello \
>      world"
$ echo $a
hello world
jcarballo
sumber
Saya khawatir ini bukan yang dimaksudkan
installero
7

Cara yang lebih aman:

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

String yang berisi spasi dapat menjadi bagian dari perintah, gunakan "$ XXX" dan "$ {XXX}" untuk menghindari kesalahan ini.

Plus lihat jawaban lain tentang + =

Bohdan
sumber
Titik string dengan spasi yang dibaca sebagai perintah muncul di titik definisi. Jadi d=DD DDakan memberikan DD: command not found--- perhatikan itu adalah DD terakhir, bukan d yang tidak ditemukan. Jika semua operan diformat dengan benar dan sudah berisi ruang yang diperlukan, Anda dapat menyatukan dengan s=${a}${b}${c}${d}; echo $s, dengan sedikit tanda kutip. Anda juga dapat menggunakan \ (escaped whitespace) untuk menghindari masalah ini --- d=echo\ echotidak akan meluncurkan permintaan gema, sedangkan d=echo echoakan.
XavierStuvw
7

Ada satu kasus khusus di mana Anda harus berhati-hati:

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

Akan menampilkan "daniel"san, dan tidak danielsan, seperti yang Anda inginkan. Dalam hal ini yang harus Anda lakukan sebagai gantinya:

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

Ini adalah bagaimana Anda menggabungkan dua string.

CodeNinjaPI
sumber
1
Ini berfungsi, tetapi kadang-kadang akan menghasilkan hasil yang tidak terduga karena interpolasi variabel tidak dilindungi. Dengan demikian, Anda tidak bisa mengandalkan formulir ini untuk semua kasus penggunaan.
Anthony Rutledge
5

Jika itu sebagai contoh Anda menambahkan " World"ke string asli, maka itu bisa:

#!/bin/bash

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

Hasil:

Hello World
nonopolaritas
sumber
5
var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3
hari
sumber
2
Juga var3=$var1\ $var2memiliki efek yang sama
XavierStuvw
5

Ada kekhawatiran yang disuarakan tentang kinerja, tetapi tidak ada data yang ditawarkan. Izinkan saya menyarankan tes sederhana.

(CATATAN: datepada macOS tidak menawarkan nanodetik, jadi ini harus dilakukan di Linux.)

Saya telah membuat append_test.sh di GitHub dengan konten:

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

Tes 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

Tes 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

Kesalahan menunjukkan bahwa Bash saya hingga 335.54432 MB sebelum crash. Anda bisa mengubah kode dari menggandakan data menjadi menambahkan konstanta untuk mendapatkan grafik yang lebih terperinci dan titik kegagalan. Tapi saya pikir ini harus memberi Anda informasi yang cukup untuk memutuskan apakah Anda peduli. Secara pribadi, di bawah 100 MB saya tidak. Jarak tempuh Anda mungkin beragam.

Bruno Bronosky
sumber
Menarik! Pertimbangkan: 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"(Coba ini pada host yang tidak produktif !!;)
F. Hauri
4

Saya ingin membuat string dari daftar. Tidak dapat menemukan jawaban untuk itu sehingga saya mempostingnya di sini. Inilah yang saya lakukan:

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

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

echo ${string}

dan kemudian saya mendapatkan output berikut:

1 2 3 4 5
simibac
sumber
4

Terlepas dari operator khusus +=, untuk penggabungan, ada cara yang lebih mudah:

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

Kutipan ganda membutuhkan waktu perhitungan ekstra untuk interpretasi variabel di dalamnya. Hindari jika memungkinkan.

Tiys
sumber
3

Perhatikan bahwa ini tidak akan berhasil

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

karena tampaknya menjatuhkan $ foo dan meninggalkan Anda dengan:

PREFIX_WORLD

tetapi ini akan berhasil:

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

dan meninggalkan Anda dengan output yang benar:

PREFIX_HELLO_WORLD

DSS
sumber
8
ini terjadi karena garis bawah adalah karakter yang valid dalam nama variabel, jadi bash melihat foo_ sebagai variabel. Bila perlu untuk memberi tahu bash batas-batas nama var yang tepat, kurung kurawal dapat digunakan: PREFIX _ $ {foo} _ $ bar
Nik O'Lai
2

Inilah yang melalui AWK :

$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
Avinash Raj
sumber
1
Bagus, Tapi saya pikir saya bisa mendapatkan lebih presisi dengan menggunakan Python!
techno
1

Saya melakukannya dengan cara ini ketika nyaman: Gunakan perintah inline!

echo "The current time is `date`"
echo "Current User: `echo $USER`"
Marty
sumber
1
Pada baris pertama, Anda bisa menjatuhkan garpu dengan menggunakan date "+The current time is %a %b %d %Y +%T":, bukan echo ...$(date). Under bash baru-baru ini, Anda bisa menulis: printf "The current time is %(%a %b %d %Y +%T)T\n" -1.
F. Hauri
1

Menurut pendapat saya, cara paling sederhana untuk menggabungkan dua string adalah dengan menulis fungsi yang melakukannya untuk Anda, lalu gunakan fungsi itu.

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

Saya agak suka membuat fungsi cepat.

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

echo $(combo 'foo''bar')

Namun cara lain untuk menguliti kucing. Kali ini dengan fungsi: D

CommaToast
sumber
Memanggil fungsi, yang juga dalam subkulit, terlalu berlebihan untuk sebuah konser sederhana.
codeforester
-1

Saya belum tahu tentang PHP, tetapi ini bekerja di Linux Bash. Jika Anda tidak ingin memengaruhi variabel, Anda dapat mencoba ini:

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

>Hello World!

Anda dapat menempatkan variabel lain alih-alih 'Halo' atau '!'. Anda dapat menggabungkan lebih banyak string juga.

Ayman Boubleh
sumber
2
Menggunakan subkulit untuk melakukan penggabungan sederhana itu terlalu mahal!
codeforester