Daftar dengan `ls` dan ekspresi reguler


15

Bagaimana saya bisa mendaftar file dengan nama file yang diakhiri dengan karakter terakhir dan dengan .txtekstensi?

Saya sudah mencoba ls *+([[:digit:]]).txttetapi ini berlaku untuk abc12.txtdan abc2.txt.

Tapi saya hanya perlu mendapatkannya abc2.txt. Bagaimana saya bisa melakukan itu?

Apakah ada bentuk apa pun :digit:yang akan melakukan ini?


2
Pola Perlu dicatat ini hanya berlaku dengan diperpanjang globbing endabled: shopt -s extglob.
Donasi berhasil pada

Jawaban:


20

Bagaimana tentang:

ls *[!0-9][0-9].txt

Pada !awal kelompok melengkapi artinya.

Seperti disebutkan dalam komentar, ini adalah bash, coba mis .:

printf "%s\n" *[!0-9][0-9].txt

2
Perhatikan bahwa bash (yaitu ls) tidak mendukung ekspresi reguler di sini. Ini adalah ekspresi nama file (Globbing) . Anda dapat melihat perbedaannya dalam contoh Anda: di sini, *adalah wildcard, yang tidak ada dalam ekspresi reguler, di mana Anda akan menggunakan .*untuk mencapai hal yang sama. Ekspresi reguler jauh lebih kuat daripada globbing.
Christopher K.

2

Pertanyaan itu meminta ekspresi reguler. Bash, dan karenanya ls, tidak mendukung ekspresi reguler di sini. Apa yang didukungnya adalah ekspresi nama file ( Globbing ), suatu bentuk wildcard. Ekspresi reguler jauh lebih kuat dari itu.

Jika Anda benar-benar ingin menggunakan ekspresi reguler, Anda dapat menggunakan find -regexseperti ini:

find . -maxdepth 1 -regex '\./.*[^0-9][0-9]\.txt'

Find bersifat rekursif secara default, tetapi lstidak. Untuk hanya menemukan file di direktori saat ini, Anda dapat menonaktifkan rekursi -maxdepth 1. Temukan kecocokan dengan nama file dengan path, itu sebabnya nama file dimulai dengan ./jika Anda menjalankan find in .. Regex dimulai dengan \./mengatasinya. Perhatikan bahwa dalam sebuah regex, .adalah karakter khusus yang cocok dengan karakter apa pun, tetapi di sini kami benar-benar menginginkan sebuah titik, itulah sebabnya kami menghindarinya dengan backslash. Kami melakukan hal yang sama untuk titik masuk .txt, karena regex juga akan cocok Atxt. Kelas digit sama dengan untuk globbing, hanya saja Anda perlu ^alih-alih !membalikkan kelas karakter.

Jika Anda ingin mendapatkan output ls, maka Anda dapat menggunakan -exec lsseperti ini:

 find . -maxdepth 1 -regex '\./.*[^0-9][0-9]\.txt' -exec ls -lah {} \;

findmendukung beberapa rasa regex yang berbeda. Anda dapat menentukan -regextype, misalnya:

find . -maxdepth 1 -regextype egrep -regex '\./.*[^0-9][0-9]\.txt'

Bagi saya, tipe yang mungkin adalah: 'findutils-default', 'awk', 'egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic' , 'posix-egrep', 'posix-extended', 'posix-minimal-basic', 'sed' Anda dapat menjalankan find -regextype helpuntuk mencari tahu apa yang didukung pada sistem Anda.


0

Dengan ksh extended globs (atau bash -O extglobatau zsh -o kshglob) yang sudah Anda gunakan, itu akan menjadi:

ls -d -- ?(*[![:digit:]])[[:digit:]].txt

Atau

ls -d -- !(*[[:digit:]])[[:digit:]].txt

Jika Anda ingin mencocokkan a1.txt dan2.txt tetapi tidak a12.txtjuga 12.txt.

Namun perhatikan bahwa dalam ksh dan bash (kecuali jika Anda mengatur failglobopsi untuk mendapatkan perilaku yang mirip dengan zsh), jika pola itu tidak cocok dengan file apa pun, pola tersebut akan diteruskan secara harfiah ke ls, dan jika file (anehnya nama) itu terjadi pada ada, itu akan terdaftar lsmeskipun tidak cocok dengan pola itu sendiri.

Untuk menyertakan .2.txt, mengatur dotglobpilihan dalam bash, menambahkan (D)kualifikasi gumpal di zsh, atau set FIGNOREke !(.|..)dalam ksh93.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.