Saya memiliki 3 direktori di jalur saat ini.
$ls
a_0db_data a_clean_0db_data a_clean_data
$ls a_*_data
a_0db_data:
a_clean_0db_data:
a_clean_data:
$ls a_[a-z]*_data
a_clean_0db_data:
a_clean_data:
Saya berharap perintah terakhir hanya cocok a_clean_data
. Mengapa itu juga cocok dengan yang mengandung 0
?
bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
bash
regular-expression
wildcards
pengguna13107
sumber
sumber
a_*_data
cocok dengan `semua file ini tidak mengejutkan Anda?Jawaban:
Bagian
[a-z]
ini tidak cocok dengan nomor tersebut; itu adalah*
. Anda mungkin membingungkan shell globbing dan ekspresi reguler .Alat seperti
grep
menerima berbagai rasa regex ( dasar secara default,-E
untuk extended,-P
untuk Perl regex )Misalnya (
-v
membalikkan pertandingan)Jika Anda ingin menggunakan bash regex, berikut adalah contoh tentang cara menguji apakah variabel
$ref
tersebut bilangan bulat:sumber
Jadi masalahnya adalah: mengapa
a_[a-z]*_data
cocoka_clean_0db_data
?Ini dapat dipecah menjadi empat bagian:
a_
cocok dengan awala_clean_0db_data
, meninggalkanclean_0db_data
untuk dicocokkan[a-z]
cocok dengan karakter apa pun dalam rentanga-z
(mis.c
), membiarkanlean_0db_data
dicocokkan*
cocok dengan sejumlah karakter, mislean_0db
_data
cocok dengan trailing_data
Dalam ekspresi reguler,
[a-z]*
berarti sejumlah karakter (termasuk nol) dalam kisaran a..z , tetapi Anda berhadapan dengan shell globbing, bukan dengan ekspresi reguler.Jika Anda ingin ekspresi reguler, beberapa
find
implementasi memiliki-regex
predikat untuk itu:The
-maxdepth
hanya di sini untuk membatasi pencarian hasil ke folder Anda berada di. The ekspresi reguler sesuai dengan seluruh nama file, karena itu saya telah menambahkan^.*/
untuk mencocokkan jalur-bagiansumber
*
dalam pola shell cocok dengan 0 atau lebih karakter. Tidak perlu bingung dengan*
operator ekspresi reguler yang berarti 0 atau lebih dari atom sebelumnya .Tidak ada padanan regexp
*
dalam pola dasar shell. Namun, berbagai shell memiliki ekstensi untuk itu.ksh
memiliki*(something)
:Anda dapat memiliki hal yang sama
bash
denganshopt -s extglob
atauzsh
dengansetopt kshglob
:Dalam
zsh
denganextendedglob
diaktifkan,#
setara dengan regexp*
:Di versi terbaru
ksh93
, Anda juga dapat menggunakan ekspresi reguler di gumpalan. Di sini dengan ekspresi reguler yang diperluas :Perhatikan bahwa
[a-z]
cocok dengan berbagai hal tergantung pada lokal saat ini. Secara umum hanya cocok 26a
kez
huruf latin non-aksen diC
lokal. Di tempat lain, umumnya lebih cocok, dan tidak selalu masuk akal. Untuk mencocokkan huruf di lokal Anda, Anda dapat memilih[[:alpha:]]
.sumber
[a-z]
lebih cocok dengan 26 huruf yang cocok dengan bahasa C? Apa yang saya ingat dari ketika saya terakhir kali melihat ini, semua pengkodean praktis digunakan dalam varian Unix memiliki ISO-646 sebagai basis (kemudian 128 kode atas di mana digunakan secara berbeda, langsung untuk karakter dalam pengkodean seperti ISO-8859-X, digabungkan dalam pengkodean seperti UTF-8 atau keluarga EUC). Bahkan AIX tidak memiliki lokal EBCDIC (setidaknya tersedia untuk saya). Saya ingat berusaha menemukan apakah standar POSIX / UNIX menuntutnya, tetapi saya tidak ingat hasilnya.[a-z]
umumnya menyertakané
atauí
(tetapi tidak harusź
) di locales tempat charset memilikinya, apakah codepoint dalam pengkodean itu antara a dan z atau tidak. Hanya lokal C yang menjamin urutan sortir berdasarkan nilai codepoint. Lihat jawaban lain ini untuk lebih jelasnya.