Apa perbedaan antara a[bc]d
dan a{b,c}d
? Mengapa orang menggunakan a{b,c}d
ketika sudah ada a[bc]d
?
ls
dan Anda hanya pernah mencoba karakter tunggal, mereka akan tampak bekerja sama.
Apa perbedaan antara a[bc]d
dan a{b,c}d
? Mengapa orang menggunakan a{b,c}d
ketika sudah ada a[bc]d
?
ls
dan Anda hanya pernah mencoba karakter tunggal, mereka akan tampak bekerja sama.
Jawaban:
Keduanya sangat berbeda.
a[bc]d
adalah pola nama file (dalam cangkang selain fish
). Ini akan diperluas ke dua nama file abd
dan acd
jika itu adalah nama file yang ada di direktori saat ini.
Bagian [...]
ini adalah ekspresi kurung yang cocok dengan satu karakter dari yang tercantum (atau menyusun elemen ketika rentang disertakan). Untuk mencocokkan pola a[bc]d
, karakter antara string a
dan d
nama file harus berupa a b
atau a c
.
Jika abd
ada, tetapi acd
tidak, maka itu hanya akan berkembang menjadi abd
, dan sebaliknya.
Jika tidak abd
, atau acd
ada, tergantung pada shell dan pilihan, itu akan memicu kesalahan (asli Unix sh
, (t)csh
, zsh
, fish
, bash -O failglob
) dan mungkin keluar dari shell, atau meninggalkan unexpanded¹ pola (Bourne-seperti dan rc
-seperti kerang) atau memperluas ke tidak ada ( bash/zsh/yash -o nullglob
, beberapa versi lama fish
, Unix asli sh
dan (t)csh
jika ada gumpalan lain yang cocok dalam perintah yang sama).
a{b,c}d
adalah ekspansi brace (di shell yang mendukung ini). Ini akan berkembang ke dua string abd
dan acd
.
Bagian tersebut {...}
adalah serangkaian string yang dibatasi koma (dalam contoh ini; dalam beberapa shell, itu juga dapat berupa rentang seperti a..k
atau 20..25
atau yang lebih maju seperti 00..20..2
atau 0..20..2%02d
), dan ekspansi dihitung dengan menggabungkan masing-masing string ini dengan sisi-sisi. string a
dan d
. String ini bisa lebih panjang dari satu karakter dan juga bisa menjadi penjepit ekspansi sendiri.
Ekspansi terjadi terlepas dari apakah string ini sesuai dengan nama file yang ada atau tidak.
Jika Anda membuat string, gunakan ekspansi brace. Jika Anda mencocokkan nama file, gunakan pola nama file.
¹ Dalam kasus khusus ini, a[bc]d
bisa jadi itu adalah nama dari file yang sudah ada yang karenanya berpotensi berbahaya untuk menggunakan hal-hal seperti rm -f ./*.[ch]
di shell itu dan rm -f ./*.{c,h}
tidak terlalu menjadi masalah.
a{b,c}d
, bagian b
dan c
tidak perlu menjadi huruf tunggal; mis ex{ten,ci}sion
. Sementara ex[tenci]sion
atau apa pun hanya akan cocok dengan salah satu dari surat-surat ini.
a[bc]d
adalah pencocokan pola , dan merupakan bagian dari standar POSIX. Dalam POSIX, ini diperkenalkan sebagai "ekspresi braket pola". Itu didokumentasikan dalam bagian 2.13 manual
Ketika tidak dikutip dan di luar ekspresi braket, tiga karakter berikut harus memiliki arti khusus dalam spesifikasi pola:
?
Tanda tanya adalah pola yang cocok dengan karakter apa pun.
*Tanda bintang adalah pola yang harus cocok dengan banyak karakter, seperti dijelaskan dalam Pola yang Cocok dengan Banyak Karakter.
[Braket terbuka harus memperkenalkan ekspresi braket pola.
Bagian 2.13.3 juga menyebutkan sesuatu yang berperilaku berbeda dari apa yang diharapkan seseorang untuk regex biasa ketika digunakan untuk ekspansi nama file (penekanan oleh saya)
Aturan yang dijelaskan sejauh ini dalam Pola Pencocokan Karakter Tunggal dan Pencocokan Pola Beberapa Karakter dikualifikasikan oleh aturan berikut yang berlaku ketika notasi pencocokan pola digunakan untuk ekspansi nama file:
Karakter garis miring dalam pathname harus dicocokkan secara eksplisit dengan menggunakan satu atau lebih garis miring dalam pola; itu tidak akan dicocokkan dengan asterisk atau karakter khusus tanda tanya atau dengan ekspresi tanda kurung. Garis miring pada pola harus diidentifikasi sebelum ekspresi braket; dengan demikian, garis miring tidak dapat dimasukkan dalam ekspresi braket pola yang digunakan untuk ekspansi nama file. Jika karakter garis miring ditemukan mengikuti karakter braket kotak terbuka yang tidak dihilangkan sebelum braket kotak penutupan yang sesuai ditemukan, braket terbuka harus diperlakukan sebagai karakter biasa. Misalnya, polanya
"a[b/c]d"
tidak cocok dengan nama path sepertiabd
ataua/d
. Ini hanya cocok dengan nama path secara harfiaha[b/c]d
.
a{b,c}d
adalah perluasan kawat gigi , tidak dalam spesifikasi oleh POSIX. Inilah bagian yang sesuai dari manual bash (penekanan oleh saya):
Perluasan Brace adalah mekanisme dimana string sewenang-wenang dapat dihasilkan. Mekanisme ini mirip dengan ekspansi nama file (lihat Ekspansi Nama File), tetapi nama file yang dihasilkan tidak perlu ada . Pola yang akan diperluas diperluas dalam bentuk pembukaan opsional , diikuti oleh serangkaian string yang dipisahkan koma atau ekspresi urutan antara sepasang kawat gigi, diikuti oleh postscript opsional . Pembukaan diawali dengan setiap string yang terkandung dalam kurung kurawal, dan naskah tambahan kemudian ditambahkan ke setiap string yang dihasilkan, meluas dari kiri ke kanan.
Menurut komentar oleh @mosvy, ini pertama kali muncul dari csh
tetapi perilaku di bash
berbeda dari csh
dan kerang lainnya. Jenis ekspansi kawat gigi juga hadir di glob(3)
.
Ada jenis lain dari ekspansi kawat gigi {a..z}
yang hanya muncul setelah bash
3.0, dan ada lebih banyak ditambahkan di bash
4.0.
Dalam shell di mana globbing dihidupkan, jalankan di folder kosong, hasil berikut dikembalikan
$ echo a[bc]d
a[bc]d
$ echo a{b,c}d
abd acd
Menanggapi komentar @ Jesse_b, jika Anda berada di shell interaktif dan keduanya berlaku, a[bc]d
lebih sedikit kesulitan mengetik. Sebagai contoh grep pattern [ab][12].txt
.
csh
, jauh sebelumnya bash
. Ini juga hadir dalam fungsi perpustakaan glob (3). Perbedaannya adalah bahwa bash
hal itu dilakukan sebelum ekspansi lain: a=A; ab=A/B; ac=A/C; echo $a{b,c}
akan bekerja di bash berbeda dari shell lain.
command a[bc]d
?