ls * .csv --ignore = "* pattern *" gibt Dateien zurück, die "pattern" enthalten.

7

Warum ls --ignoreignoriert man das Muster nicht?

Betrachten Sie das folgende Beispiel:

mkdir books
cd books
touch books_abby.csv
touch books_karen.csv
touch books_david.csv
touch books_tom.csv

Dadurch werden vier Dateien erstellt:

$ ls
books_abby.csv  books_david.csv  books_karen.csv  books_tom.csv

Wenn Sie jedoch alle Dateinamen mit "tom" ignorieren und auflisten möchten, books_tom.csvwird immer noch Folgendes zurückgegeben:

$ ls *.csv --ignore="*tom*"
books_abby.csv  books_david.csv  books_karen.csv  books_tom.csv

Das erwartete Ergebnis ist, dass Dateien, die "tom" enthalten, weggelassen werden:

$ ls *.csv --ignore="*tom*"
books_abby.csv  books_david.csv  books_karen.csv
Greg
quelle

Antworten:

11

Die Flagge wird in der lsManpage so beschrieben (Hervorhebung liegt bei mir) ...

Listen Sie keine impliziten Einträge auf, die mit dem Shell-MUSTER übereinstimmen

Die Manpage hat nicht viel über "impliziert" zu sagen. Was zum Teufel bedeutet das? Ein impliziter Eintrag (Datei, Verzeichnis usw.) ist ein Eintrag, der zurückgegeben lswird, ohne dass Sie explizit ein Argument angegeben haben, das diesem Eintrag entspricht. Eine Übereinstimmung kann entweder der tatsächliche Name des Eintrags sein ( ls books_tom.csv ...anhand Ihres Beispiels) oder ein Glob, der mit ihm übereinstimmt ( ls *tom.csvz. B.).

Wenn Sie lsohne Argumente aufrufen , ist alles, was zurückgegeben wird, impliziert! Ich gehe davon aus, dass die häufigste Verwendung von --ignoreeinem solchen ansonsten schmucklosen lsAufruf ist, da dies der einfachste Weg ist, eine Operation "Alles außer X auflisten" durchzuführen ... zumindest, wenn Sie die Verwendung anderer Befehle vermeiden möchten.

Schauen wir uns also Ihren Befehl an. Bei ls *.csv --ignore="*tom*""books_tom.csv" wird explizit über das passende Muster verwiesen *.csv. Mit ls --ignore="*tom*", gemäß dem vorherigen Absatz, ist alles im Verzeichnis impliziert, so dass "books_tom.csv" nicht angezeigt wird.

Wenn in Ihrer Shell erweitertes Globbing verfügbar ist (mit Bash, das Sie aktivieren können shopt -s extglob), können Sie das erreichen, was Sie möchten, indem Sie ein Muster erstellen, das "Tom" ausschließt. Zum Beispiel ls books_!(tom).csvwürde sich books_abby.csvaber nicht zeigen books_tom.csv.

(Natürlich können Sie auch andere Tools wie findPipe to grep -vusw. verwenden. Ich gebe nur eine reine lsLösung.)

B Schicht
quelle
Gibt es eine Möglichkeit, das gewünschte Verhalten ohne zu erreichen grep?
Greg
Ich habe die versuchte ls books_!(tom).csvLösung und es funktioniert :) Mein tatsächlicher Anwendungsfall hat Daten in den Dateinamen (zB 2017_10_29) und ich versuche , ohne das Datum eine Liste aller Dateien zu erhalten verwenden ls *_!(2017_10_29).csvund ls *_!("2017_10_29").csvaber es gibt immer noch Dateien von diesem Zeitpunkt an einer Idee Warum?
Greg
Ja, weil books_2017_das mit *_und 10_29.csvübereinstimmt !(2017_10_29).csv. Wenn Sie das verwenden books_!(2017_10_29).csv, würde das funktionieren. Es ist besser, wenn Sie explizitere Muster verwenden, da dies *sehr flexibel ist.
B-Schicht
3
@ Greg es klingt wirklich so, als ob Sie find(z. B. find . -name '*csv' -not -name '*2017_10_29*') verwenden sollten oder, vorausgesetzt Ihre Dateinamen haben kein Leerzeichen oder andere seltsame Zeichen, nur ls *csv | grep -v 2017_10_29.
Terdon
@terdon Danke, dieser Ansatz ist eigentlich alles, wonach ich gesucht habe
Greg