Wie werden case-unempfindliche Muster mit ls verglichen?

57

Ich möchte alle Dateien auflisten, die einem bestimmten Muster entsprechen, ohne den Fall zu beachten.

Zum Beispiel führe ich die folgenden Befehle aus:

ls *abc*

Ich möchte alle Dateien sehen, die "abc" als Teil des Dateinamens haben und dabei den Fall ignorieren, wie

-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

Hinweis

Ich habe die Manpage nach Fall durchsucht, aber nichts gefunden.

mtk
quelle

Antworten:

65

Dies wird tatsächlich von Ihrer Shell erledigt, nicht von ls.

In würden bashSie verwenden:

shopt -s nocaseglob

und führen Sie dann Ihren Befehl aus.

Oder in zsh:

unsetopt CASE_GLOB

Oder in Yash:

set +o case-glob

und dann dein Befehl.

Vielleicht haben Sie , dass in setzen wollen .bashrc, .zshrcoder .yashrcsind.

Alternativ mit zsh:

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

(Das ist wiederum case insensitive Globbing auf einer Pro-Wildcard-Basis)

Mit ksh93:

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

Sie möchten, dass das Globbing anders funktioniert ls, da dies alle Dateien sind, die lsvon der Shell übergeben werden.

Polemon
quelle
Wie kann ich in bash die ursprüngliche Einstellung wiederherstellen, wenn ich verwende shport -s nocaseglob?
MTK
6
@mtk: Um setzt eine Option, die Sie verwenden shopt -s; Um es zu deaktivieren , verwenden Sie shopt -u. Alternativ können Sie alles in einer Subshell wickeln , indem Sie ( )so , dass die Einstellung nicht mit den Eltern - Shell nicht beeinflusst: (shopt -s nocaseglob ; ls *abc*).
Ruakh
Also gibt es keine tragbaren Möglichkeiten dafür in POSIX oder SUS oder so etwas (außer [aA][bB][cC])?
Timothy Gu
Hervorragende Lösung, ich kann nicht glauben, dass ich shoptin den letzten 15 Jahren bei der Verwendung von Bash nicht auf Kommando gestoßen bin !
Reza Sanaie
Die Antwort von Jfg956 ist die richtige (nächste). Warum sollte man das Shell-Verhalten ändern, wenn man dafür einen regulären Ausdruck hat?
EnzoR
20

Wie von polemon erklärt, ist es die Shell (nicht ls), die sich *abc*auf eine Liste von Dateien erstreckt. Dies wird als Mustervergleich bezeichnet .

Abgesehen von der Änderung des gesamten Pattern Matching-Verhaltens, um Groß- und Kleinschreibung zu ignorieren, können Sie auch eine andere Form des Pattern Matching als das verwenden *. Folgendes würde tun, was Sie in der Bash wollen:

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

Von bash man:

[...] Stimmt mit einem der beigefügten Zeichen überein.

Dies ermöglicht mehr feinkörnig Matching , wo man verwenden könnte *[aA][bB]c*passen abcoder ABcaber nicht abCoder ABC. Oder ein Beispiel in Französisch, in dem ich alle Instanzen des eZeichens finden möchte :

ls *[eéèêëEÉÈÊË]*
jfg956
quelle
1
Leider wird dieser Ansatz schnell unhandlich, wenn das Muster länger wird. Aber für kurze Dinge funktioniert es.
Derobert
@derobert: Ganz richtig, vor allem, wenn (und wahrscheinlich auch) die Shell die Groß- und Kleinschreibung des Übereinstimmungs-Ignorierens optimiert hat, indem alle Dateinamen und die Übereinstimmungsanforderung vor dem Vergleich in Kleinbuchstaben gesetzt wurden. Das [...]kann jedoch in vielen Fällen nützlich sein, und ich dachte, es wäre erwähnenswert.
jfg956,
1
Das ist die richtige Antwort. Ändern Sie das Shell-Verhalten nicht.
EnzoR
Wenn das Gebietsschema richtig festgelegt ist, sollten Sie in der Lage sein, Äquivalenzklassen zu verwenden [[=e=][=E=]].
Benjamin W.
8

Sie können auch die -iOption (--ignore-case) hinzufügen grep, um die folgende Ausgabe zu erhalten.

[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
Mischling
quelle
Der Mustervergleich hat eine bessere Leistung als grep, da grep alles sammeln und dann filtern muss. Hat einen spürbaren Unterschied beim Arbeiten mit größeren Ordnern.
Omi
@Omi Zusätzlich reguläre Ausdrücke sind für Text , speziell Zeilen Text. Dateinamen können Zeilenumbrüche enthalten.
Kusalananda
3

Ich denke nicht, dass dies mit ls möglich ist, aber Sie könnten stattdessen find verwenden:

find . -maxdepth 1 -iname '*abc*'
Matte
quelle
0

benutze den folgenden Code:

LC_COLLATE=en_US ; export LC_COLLATE
ls *abc*
LC_COLLATE=C ; export LC_COLLATE
user1678213
quelle
Wofür ist die Variable LC_COLLATE? kannst du weiter erklären.
MTK
Klicken Sie auf den Link , um mehr über diesen @mtk
user1678213
0

Sie können die Datei mit -ider Option "Unempfindlich" GREPEN.

Zum Beispiel beide zu finden abcund ABCSie können diesen Befehl ausführen

    [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
quelle
5
Luis Perez Ich glaube, Sie haben keine -iOption in Ihrem Befehl verwendet.
Mischling
-2

Legen Sie in tcsh einen Alias ​​in .aliases fest

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

("BS" = ein "Backslash"; ich musste diesen verwenden, um ihn in meinem Browser anzuzeigen.)

und verwenden Sie lsncstattls

Versuchen Sie in bash einen Alias ​​in .bash_aliases wie

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

Mit Optionen zum lsBeispiel ls -list hier eine einfache Lösung:

tcsh:

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

bash:

lsncl() { ls -l $1 | sort -f -k 9 ; }
Lester Ingber
quelle
Sind Sie sicher, dass Sie =nach lsnocase kein ' ' verpassen?
Anthon
Anthon: Die (überarbeiteten) lsnc und lsncl funktionieren für mich unter tcsh und bash auf Cygwin und Ubuntu. Beachten Sie, dass ich für bash eine Funktion verwende, keinen "Alias" an sich. Lester
Lester Ingber
Anthon: Ja, Sie können wahrscheinlich einen Alias ​​in bash verwenden, wie zB lsncl = 'ls -l $ 1 | sort -f -k 9 '
Lester Ingber
Diese Antwort geht nicht auf die spezifische Frage ein, bei der die an ls übergebenen Dateien als nicht zwischen Groß- und Kleinschreibung unterschiedene Dateien behandelt werden sollen. Übergibt die Shell zu wenige Dateien an ls, gibt es nichts lsund sortkann das Problem beheben. Wie in anderen Antworten erwähnt, muss das Problem in der Shell und nicht mit einer lsSyntax gelöst werden .
Mark Stosberg