Bagaimana mencocokkan pola peka huruf besar-kecil dengan ls?

57

Saya ingin mendaftar semua file yang cocok dengan pola tertentu sambil mengabaikan kasingnya.

Sebagai contoh, saya menjalankan perintah berikut:

ls *abc*

Saya ingin melihat semua file yang memiliki "abc" sebagai bagian dari nama file, seperti mengabaikan case

-rw-r--r-- 1 mtk mtk 0 Sep 21 08:12 file1abc.txt
-rw-r--r-- 1 mtk mtk 0 Sep 21 08:12 file2ABC.txt

Catatan

Saya telah mencari halaman manual untuk kasus, tetapi tidak dapat menemukan apa pun.

mtk
sumber

Jawaban:

65

Ini sebenarnya dilakukan oleh shell Anda, bukan oleh ls.

Di bash, Anda akan menggunakan:

shopt -s nocaseglob

dan kemudian jalankan perintah Anda.

Atau di zsh:

unsetopt CASE_GLOB

Atau di yash:

set +o case-glob

dan kemudian perintahmu.

Anda mungkin ingin memasukkannya ke dalam .bashrc, .zshrcatau .yashrc, masing-masing.

Atau, dengan zsh:

setopt extendedglob
ls -d -- (#i)*abc*

(yaitu pembalikan kasing case turn case berdasarkan per-wildcard)

Dengan ksh93:

ls -d -- ~(i:*abc*)

Anda ingin globbing bekerja berbeda, bukan ls, karena itu semua file yang diteruskan lsoleh shell.

polemon
sumber
Di bash, cara mengatur ulang ke pengaturan asli, Jika saya gunakan shport -s nocaseglob?
mtk
6
@ mtk: Untuk mengatur opsi, Anda menggunakan shopt -s; untuk menghapusnya , Anda gunakan shopt -u. Atau, Anda dapat membungkus segala sesuatu di subkulit dengan menggunakan ( )sehingga pengaturan tersebut tidak mempengaruhi shell orang tua: (shopt -s nocaseglob ; ls *abc*).
ruakh
Jadi tidak ada cara portabel untuk ini dalam POSIX atau SUS atau sesuatu seperti itu (kecuali untuk [aA][bB][cC])?
Timothy Gu
Solusi luar biasa, saya tidak percaya saya belum menemukan shoptperintah dalam 15 tahun terakhir menggunakan bash!
Reza Sanaie
Jawaban Jfg956 adalah yang benar (yang berikutnya). Mengapa mengubah perilaku shell ketika Anda memiliki regexp untuk itu?
EnzoR
20

Seperti yang dijelaskan oleh polemon, itu adalah shell (bukan ls) yang meluas *abc*ke daftar file. Ini disebut Pencocokan Pola .

Selain mengubah seluruh perilaku Pencocokan Pola untuk mengabaikan huruf besar-kecil, Anda bisa menggunakan bentuk lain dari pola yang cocok dengan *. Berikut ini akan melakukan apa yang Anda inginkan dalam bash:

ls *[aA][bB][cC]*

Dari bash man:

[...] Cocok dengan salah satu karakter yang terlampir.

Ini memungkinkan lebih banyak pencocokan biji-bijian halus di mana Anda dapat menggunakan *[aA][bB]c*untuk mencocokkan abcatau ABctetapi tidak abCatau ABC. Atau contoh dalam bahasa Prancis, di mana saya ingin mencocokkan semua contoh ekarakter:

ls *[eéèêëEÉÈÊË]*
jfg956
sumber
1
Sayangnya, pendekatan itu dengan cepat menjadi sulit karena polanya menjadi lebih panjang. Tetapi untuk hal-hal pendek, itu berhasil.
derobert
@derobert: sepenuhnya benar, terutama (dan mungkin memang begitu) shell telah mengoptimalkan case yang cocok dengan mengabaikan semua nama file dan permintaan pertandingan dalam huruf kecil sebelum membandingkan. Namun, [...]bisa bermanfaat dalam banyak kasus, dan saya pikir itu layak disebutkan.
jfg956
1
Ini adalah jawaban yang benar. Mengubah perilaku shell tidak.
EnzoR
Jika lokal diatur dengan benar, Anda harus dapat menggunakan kelas kesetaraan [[=e=][=E=]].
Benjamin W.
8

Anda juga dapat menambahkan -iopsi (--ignore-case) grepuntuk mendapatkan dan keluaran di bawah ini.

[root@localhost ~]# ls -l | grep -i abc
-rw-r--r--  1 root root    0 Feb 25 20:41 fileabc.txt
-rw-r--r--  1 root root    0 Feb 25 20:41 fileABC.txt
Anjing kampung
sumber
Pencocokan pola memiliki kinerja yang lebih baik dibandingkan dengan grep karena grep perlu mengumpulkan semuanya lalu memfilter. Memiliki perbedaan yang nyata saat bekerja dengan folder yang lebih besar.
Omi
@ Omi Selain itu, ekspresi reguler adalah untuk teks , khususnya baris teks. Nama file mungkin berisi baris baru.
Kusalananda
3

Saya tidak berpikir ini mungkin dengan ls, tetapi Anda dapat menggunakan find sebagai gantinya:

find . -maxdepth 1 -iname '*abc*'
tikar
sumber
0

gunakan kode berikut:

LC_COLLATE=en_US ; export LC_COLLATE
ls *abc*
LC_COLLATE=C ; export LC_COLLATE
pengguna1678213
sumber
Untuk apa variabel LC_COLLATE? dapatkah kau jelaskan lebih lanjut
mtk
klik pada tautan untuk mengetahui tentang @mtk ini
user1678213
0

Anda dapat melakukan GREP pada file -iyang menambahkan opsi tidak sensitif.

Misalnya untuk menemukan keduanya abcdan ABCAnda dapat menjalankan perintah ini

    [root@mtk bin]# ls -l | grep -i abc
    640K -rw-r--r-- 1 mtk mtk 639K Sep 21 08:12 file1abc.txt
    676K -rw-r--r-- 1 mtk mtk 674K Sep 21 08:12 file2ABC.txt
Luis Perez
sumber
5
Luis Perez Saya pikir Anda belum menggunakan -iopsi di mana pun dalam perintah Anda.
Mongrel
-2

Di tcsh, atur alias di .aliases

alias lsnc "ls BS!* | sort -f "

("BS" = one "backslash"; Saya harus menggunakan ini untuk membuatnya muncul di browser saya.)

dan gunakan lsncsebagai gantinyals

Di bash, coba alias di .bash_aliases like

lsnc() { ls $1 | sort -f ; }

Dengan opsi untuk ls, mis. ls -l, Di sini adalah perbaikan sederhana:

tcsh:

alias lsncl "ls -l BS!* | sort -f -k 9"

pesta:

lsncl() { ls -l $1 | sort -f -k 9 ; }
Lester Ingber
sumber
Apakah Anda yakin tidak melewatkan ' =' setelah lsnocase?
Anthon
Anthon: The lsnc dan lsncl (direvisi) bekerja untuk saya di bawah tcsh dan bash pada Cygwin dan Ubuntu. Perhatikan bahwa untuk bash, saya menggunakan fungsi, bukan "alias" per se. Lester
Lester Ingber
Anthon: Ya, Anda mungkin dapat menggunakan alias di bash, seperti alias lsncl = 'ls -l $ 1 | sort -f -k 9 '
Lester Ingber
Jawaban ini tidak menjawab pertanyaan spesifik yang ingin meneruskan file yang diteruskan ke ls untuk diperlakukan sebagai case-insensitive. Jika shell melewati terlalu sedikit file ke ls, tidak ada lsdan sortbisa untuk memperbaiki situasi. Seperti dicatat dalam jawaban lain, masalah perlu diselesaikan di shell, bukan dengan lssintaks.
Mark Stosberg