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.

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.


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ÉÈÊË]*

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

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*'

0

użyj następującego kodu:

LC_COLLATE=en_US ; export LC_COLLATE
ls *abc*
LC_COLLATE=C ; export LC_COLLATE

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

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 ; }

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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.