Jak dopasować wzorce bez rozróżniania wielkości liter do ls?

57

Chciałbym wyświetlić listę wszystkich plików pasujących do określonego wzorca, ignorując wielkość liter.

Na przykład uruchamiam następujące polecenia:

ls *abc*

Chcę zobaczyć wszystkie pliki, które mają „abc” jako część nazwy pliku, ignorując wielkość liter

-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

Uwaga

Przeszukałem stronę podręcznika w poszukiwaniu sprawy, ale nic nie znalazłem.

Mt.
źródło

Odpowiedzi:

65

W rzeczywistości jest to wykonywane przez powłokę, a nie przez ls.

W bashużyłbyś:

shopt -s nocaseglob

a następnie uruchom polecenie.

Lub w zsh:

unsetopt CASE_GLOB

Lub w yash:

set +o case-glob

a potem twoje polecenie.

Może chcesz umieścić to pod .bashrc, .zshrclub .yashrc, odpowiednio.

Alternatywnie, z zsh:

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

(tzn. globowanie bez rozróżniania wielkości liter na podstawie symboli wieloznacznych)

Z ksh93:

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

Chcesz, aby globowanie działało inaczej, lsponieważ są to wszystkie pliki przekazywane do lspowłoki.

polemon
źródło
W bash, jak zresetować do oryginalnego ustawienia, jeśli używam shport -s nocaseglob?
mtk
6
@mtk: Aby ustawić opcję, użyj shopt -s; aby go rozbroić , używasz shopt -u. Alternatywnie, można zawinąć wszystko w podpowłoce za pomocą ( )tak, że ustawienie nie ma wpływu na powłokę nadrzędny: (shopt -s nocaseglob ; ls *abc*).
ruakh
Więc nie ma żadnych przenośnych sposobów na to w POSIX lub SUS czy coś takiego (oprócz [aA][bB][cC])?
Timothy Gu
Doskonałe rozwiązanie, nie mogę uwierzyć, że nie spotkałem się z shoptdowództwem w ciągu ostatnich 15 lat używania bash!
Reza Sanaie
Odpowiedź Jfg956 jest właściwa (następna). Po co zmieniać zachowanie powłoki, jeśli masz do tego wyrażenie regularne?
EnzoR
20

Jak wyjaśnił polemon, to powłoka (nie ls) rozciąga *abc*się na listę plików. Nazywa się to dopasowaniem wzorca .

Oprócz zmiany całego zachowania Dopasowanie wzorca w celu zignorowania wielkości liter, możesz użyć innej formy dopasowania wzorca niż *. Następujące czynności zrobią, co chcesz w bash:

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

Od bash mana:

[...] Dopasowuje dowolny z zamkniętych znaków.

Pozwala to na bardziej cienkiej dopasowanie ziarna gdzie można użyć *[aA][bB]c*, aby dopasować abclub ABcale nie abClub ABC. Lub przykład w języku francuskim, w którym chciałbym dopasować wszystkie wystąpienia epostaci:

ls *[eéèêëEÉÈÊË]*
jfg956
źródło
1
Niestety, takie podejście szybko staje się niewygodne, gdy wzór staje się dłuższy. Ale w skrócie działa.
derobert
@derobert: całkowicie prawda, zwłaszcza, że ​​(i prawdopodobnie tak jest) powłoka zoptymalizowała dopasowanie ignorując wielkość liter, umieszczając wszystkie nazwy plików i żądanie dopasowania w małych literach przed porównaniem. Jednak [...]mogą być przydatne w wielu przypadkach i myślałem, że warto o tym wspomnieć.
jfg956
1
To jest właściwa odpowiedź. Zmiana zachowania powłoki nie jest.
EnzoR
Jeśli ustawienia regionalne są ustawione poprawnie, powinieneś mieć możliwość korzystania z klas równoważności [[=e=][=E=]].
Benjamin W.
8

Możesz także dodać -iopcję (--ignore-case), grepaby uzyskać i poniższe wyjście.

[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
Kundel
źródło
Dopasowywanie wzorców ma lepszą wydajność w porównaniu do grep, ponieważ grep musi zebrać wszystko, a następnie filtrować. Ma zauważalną różnicę podczas pracy z większym folderem.
Omi
@Omi Ponadto wyrażenia regularne dotyczą tekstu , a konkretnie wierszy tekstu. Nazwy plików mogą zawierać znaki nowej linii.
Kusalananda
3

Nie sądzę, że jest to możliwe w przypadku ls, ale zamiast tego możesz użyć find:

find . -maxdepth 1 -iname '*abc*'
mata
źródło
0

użyj następującego kodu:

LC_COLLATE=en_US ; export LC_COLLATE
ls *abc*
LC_COLLATE=C ; export LC_COLLATE
użytkownik1678213
źródło
Do czego służy zmienna LC_COLLATE? czy możesz wyjaśnić dalej.
Mt
kliknij link, aby dowiedzieć się o tym @mtk
user1678213
0

Możesz ZROBIĆ plik, -iktóry dodaje opcję niewrażliwą.

Na przykład, aby znaleźć jedno abci drugie ABC, możesz uruchomić to polecenie

    [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
źródło
5
Luis Perez Myślę, że -inigdzie nie użyłeś opcji w swoim poleceniu.
Mongrel
-2

W tcsh ustaw alias w .aliases

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

(„BS” = jeden „ukośnik odwrotny”; musiałem go użyć, aby pojawił się w przeglądarce).

i użyj lsnczamiastls

W bash wypróbuj alias w .bash_aliases, np

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

Z opcjami lsnp. ls -lTutaj jest prosta poprawka:

tcsh:

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

grzmotnąć:

lsncl() { ls -l $1 | sort -f -k 9 ; }
Lester Ingber
źródło
Czy na pewno nie brakuje ci =lsnocase?
Anthon
Anthon: (poprawione) lsnc i lsncl działają dla mnie pod tcsh i bash na Cygwin i Ubuntu. Zauważ, że do bash używam funkcji, a nie „aliasu” jako takiego. Lester
Lester Ingber
Anthon: Tak, prawdopodobnie możesz użyć aliasu w bash, jak alias lsncl = 'ls -l $ 1 | sort -f -k 9 '
Lester Ingber
Ta odpowiedź nie odnosi się do konkretnego pytania, które chce przekazać pliki przekazane do ls, aby traktować je jako bez rozróżniania wielkości liter. Jeśli powłoka przejdzie, przekazuje za mało plików ls, nie ma nic lsi sortmoże naprawić sytuację. Jak zauważono w innych odpowiedziach, problem musi zostać rozwiązany w powłoce, a nie w lsskładni.
Mark Stosberg,