Apa perbedaan antara ls [13] dan ls {1,3}?

11

Saya membuat tiga file di direktori saya menggunakan perintah touch inv{1..3}.txt. Sekarang saya menggunakan dua perintah dan hasilnya hampir sama. Kedua perintah itu adalah ls inv[13].txtdan ls {1,3}.txt.

Jadi bagaimana keduanya berbeda? Bagaimana tanda kurung siku berbeda dengan kawat gigi? Saya juga mencari Google untuk "linux [..]", tetapi tidak dapat menemukan apa-apa, jadi bisakah saya tahu apa yang disebut dalam istilah linux?

Terima kasih

posixKing
sumber
2
Nama untuk ini adalah "ekspansi nama file" atau "globbing".
Byte Commander
Manakah dari ini adalah ekspansi nama file atau globbing? Apakah braket persegi ([..]) atau braket bunga ({..})?
posixKing
Kunjungi Ekspansi Brace untuk {}dan Ekspansi Nama File> Pencocokan Pola untuk [].
Pandya

Jawaban:

14
  • {}disebut ekspansi brace. Ini memiliki dua bentuk: {x..y}dan {x,y}, ganti xdan ydengan nilai alfabet atau numerik.

    Dalam bentuk pertama, {x..y}akan diperluas untuk semua nilai dari xke y, inklusif. Sebagai contoh, {2..5}akan diperluas untuk 2, 3, 4, 5.

    Dalam bentuk eksplisit kedua, {x,y}akan diperluas hanya x, y. Misalnya, {2,5}akan diperluas ke 2dan 5.

    Jika tidak ada ekspansi yang dimungkinkan, polanya diperlakukan secara harfiah misalnya dalam {a..3}.

    Hal penting yang perlu diperhatikan adalah bahwa ekspansi brace akan dilakukan (jika mungkin) terlepas dari kecocokan file apa pun, saat dalam pembuatan / pencocokan file.

  • []dikenal sebagai pola ekspansi pathname (atau globbing). Tidak seperti ekspansi brace, Anda hanya dapat menggunakannya saat mencocokkan nama file, itu akan diperlakukan secara harfiah jika Anda menggunakannya saat membuat file.

    Ini memiliki dua bentuk: [xyz...]dan [x-y].

    Dalam bentuk pertama, itu akan cocok dengan karakter tunggal di dalam tanda kurung secara terpisah. Yaitu setiap karakter diperlakukan secara individual. Jadi untuk [25].txtitu akan cocok dengan file bernama 2.txtatau 5.txtdi direktori saat ini, sedangkan untuk [245].txtitu akan cocok dengan file apa pun yang bernama 2.txtatau 4.txtatau 5.txt.

    Dalam bentuk kedua, ekspansi jangkauan dilakukan terlebih dahulu sebelum mencocokkan secara individual, jika mungkin diperlakukan secara harfiah. Jadi untuk [2-5]. txt, itu akan cocok dengan file apa pun yang bernama 2.txtatau 3.txtatau 4.txtatau 5.txt. Jika rentang tidak dapat diperluas, itu akan diperlakukan secara harfiah misalnya dalam kasus [a-3].txt.


Perbedaan perilaku yang penting antara keduanya adalah ketika ada lebih banyak pola yang cocok sementara yang sebenarnya kurang cocok. Karena ekspansi brace dilakukan tidak peduli apa pun, itu akan menunjukkan kesalahan bahwa file-file tertentu tidak ada sementara ekspansi pathname akan cocok dengan apa pun yang mungkin tanpa kesalahan untuk sisanya:

$ ls {1..4}.txt
ls: cannot access 4.txt: No such file or directory
1.txt  2.txt  3.txt

$ ls [1-4].txt
1.txt  2.txt  3.txt

Catatan Portabilitas:

The []Operator ekspansi path didefinisikan oleh POSIX maka portabel di antara Bourne shell dan turunannya.

Perluasan brace,, {}tidak didefinisikan oleh POSIX sehingga tidak portabel di antara semua shell. Misalnya, dash( shdalam Ubuntu) tidak memiliki ini. Hal itu dipinjam dari cshdan akan bekerja pada kulit tertentu saja misalnya bash, zsh, ksh93, fish. Pastikan shell yang Anda gunakan mendukung ini sebelum menerapkan.


Contoh:

$ touch {1..3}.txt

$ ls {1..3}.txt
1.txt  2.txt  3.txt

$ ls {1,2,3}.txt
1.txt  2.txt  3.txt

$ ls {1..4}.txt
ls: cannot access 4.txt: No such file or directory
1.txt  2.txt  3.txt

$ ls {a..3}.txt
ls: cannot access {a..3}.txt: No such file or directory

$ ls [123].txt
1.txt  2.txt  3.txt

$ ls [1-3].txt
1.txt  2.txt  3.txt

$ ls [1-4].txt
1.txt  2.txt  3.txt

$ ls [a-3].txt
ls: cannot access [a-3].txt: No such file or directory
heemayl
sumber
1
Orang harus menghindari mengandalkan perilaku [ ]ekspansi ketika tidak ada kecocokan karena itu bisa berbeda tergantung pada konfigurasi shell. Jika Anda ingin menggunakan [atau ]dalam nama file, itu harus dikutip dalam perintah Anda. Perlu juga diperhatikan perbedaan antara {13..79}dan [13-79]. Yang pertama akan menghasilkan semua angka di kisaran dari 13ke 79, kedua akan cocok dengan karakter 1, 3, 4, 5, 6, 7, dan 9.
kasperd
@kasperd Ya, untuk itulah nullglob(atau serupa). Tentang [13-79]pencocokan, saya pikir saya sebutkan dengan jelas dalam jawaban saya tentang perilaku per karakter [] `.
heemayl
@ heemayl Saya pikir akan layak juga menyebutkan bahwa bentuk `{1..3}` adalah bashism. Ini tidak akan bekerja dengan cepat. Saya pikir kshmemiliki fitur ini, tetapi bukan itu rasa yang lebih modern, seperti mksh dan pkdsh
Sergiy Kolodyazhnyy
@Erg menambahkan catatan portabilitas.
heemayl
7

Perbedaan utama antara kedua bentuk tersebut diilustrasikan di sini:

$ ls inv[15].txt
inv1.txt
$ ls inv{1,5}.txt
ls: cannot access 'inv5.txt': No such file or directory
inv1.txt

inv[15].txtadalah glob dan akan memperluas daftar file yang cocok pada sistem file Anda. Ini adalah perluasan pathname .

inv{1,5}.txtmemperluas ke inv1.txtdan inv5.txtterlepas dari file apa yang sebenarnya ada di sistem file Anda. Ini adalah ekspansi brace .

John1024
sumber
Perbedaan utama lainnya adalah Anda dapat menulis ba{con,tman}dan tidak ada yang setara dengan menggunakan tanda kurung. TKI, ekspansi brace tidak hanya untuk karakter tunggal.
hobbs