Dateien auflisten, die mit einem Muster übereinstimmen, aber Dateien ignorieren, die mit einem anderen Muster übereinstimmen?


12

Angenommen, ich habe ein Verzeichnis mit den Dateien a1, a2, a3, b1, b2, b3. Ich möchte nur Dateien finden, die anfangen, aaber keine enthalten 3. Ich habe es versucht, ls -I "*3" *a*aber es kehrt zurück a1 a2 a3, obwohl ich nicht möchte, dass es übereinstimmt a3. Ist das möglich mit ls?


Interessante und vielfältige Antworten, aber eine Erklärung, warum ls -I '* 3' a * fehlschlägt, wäre erbaulich. und / oder warum wird die Globbed-Liste der Shell nicht anschließend durch den Ignore-Schalter auf ls gefiltert?
Theophrastus

Die Manpage sagt über die Option -I: do not list implied entries matching shell PATTERN, aber es nicht erklären , was gemeint ist mit impliziert , aber ich vermute , es nur auf Dateien angewandt wird, die lsdurch glob Erweiterungen bekommt - und lsnicht die nicht erweitern a*, die Shell tut, .
Murray Jensen

Antworten:


14

Gerade:

shopt -s extglob  
ls a!(*3*)
  • shopt -s extglob Aktiviert erweitertes Globbing.
  • a passt zum Start a
  • !()annulliert das Streichholz im ()...
    • *3*was ist 3und irgendetwas davor oder danach.

$ touch 1 2 3 a1 a2 a3 b1 b2 b3 aa1 aa2 aa3 a2a a3a
$ ls a!(*3*)
a1  a2  a2a  aa1  aa2

1
Zu Ihrer Information, erfordertset -s extglob
Brian

@ Brian Yea, gerade bemerkt ^^
Chaos

8

Bestehende Antworten geben den besten Weg an, dies mit Globs zu tun. Ich werde dies einschließen, da in den meisten Fällen findeine bessere Option ist, wenn Sie Skripte erstellen oder weiter verarbeiten möchten:

$ find . -maxdepth 1 -name 'a*' -not -name '*3*'
./a1
./a2

Sie können die Antwort an xargseinfache Aktionen oder an eine while readSchleife für kompliziertere Dinge senden.


4

Ein einfacher Weg ist

  • um alle passenden Dateien aufzulisten a*
  • dann lösche alle Zeilen mit a 3

Der UNIX-Befehl lautet

ls -1 a* | grep -v 3

ls -1 zeigt eine Datei pro Zeile.

grepNormalerweise werden Linien gefunden, die mit einem Muster übereinstimmen, aber -vdieses Verhalten ist invertiert.


2
Hallo Peter! Erklären Sie am besten so ausführlich wie möglich, wie Ihre Lösung funktioniert.
Dhag

2
Parsing lsist keine gute Idee: mywiki.wooledge.org/ParsingLs
Chaos

3

Mit zsh, unter Verwendung des ~ Glob-Operators :

setopt extendedglob
print -rl -- a*~*3*

Mit gnu lskönnten Sie zwei --ignoreMöglichkeiten nutzen:

ls -I '[^a]*' -I '*3*'

Die erste ignoriert alle Dateinamen, die nicht mit "" beginnen, aund die zweite ignoriert Dateinamen, die "" enthalten3

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.