Listen Sie Dateien mit bestimmten Erweiterungen mit ls und grep auf

151

Ich möchte nur die Dateien aus dem aktuellen Verzeichnis abrufen und nur .mp4 .mp3 .exe-Dateien ausgeben, sonst nichts. Also dachte ich, ich könnte das einfach machen:

ls | grep \.mp4$ | grep \.mp3$ | grep \.exe$

Aber nein, da der erste grep nur mp4s ausgibt, werden die anderen 2 grep's nicht verwendet.

Irgendwelche Ideen? PS: Führen Sie dieses Skript auf Slow Leopard aus.

Minze
quelle
1
Dies ist wirklich der falsche Ansatz - anstatt grep zu verwenden, verwenden Sie shopt -s nullglobund verweisen Sie dann einfach auf *.exe *.mp3 *.mp4. Siehe mywiki.wooledge.org/ParsingLs
Charles Duffy
1
Ich kann nicht herausfinden, ob "Slow Leopard" ein Tippfehler war oder nicht ...
Wowfunhappy
1
@Wowfunhappy hahaha, war definitiv ein Tippfehler, ich erinnere mich, dass Snow Leopard ziemlich schnell war.
Münze

Antworten:

334

Warum nicht:

ls *.{mp3,exe,mp4}

Ich bin mir nicht sicher, wo ich es gelernt habe - aber ich habe es benutzt.

meder omuraliev
quelle
1
Dies funktioniert bei mir nicht, da die von mir verwendete Erweiterung für ein Verzeichnis gilt und das ls den Inhalt des Verzeichnisses auflistet.
Richard Venable
1
@RichardVenable Fügen Sie den Schalter -d hinzu, um zu verhindern, dass Verzeichnisse erneut verwendet werden.
Carlos Eugenio Thompson Pinzón
11
Ich mag diese Lösung, aber es scheint zu scheitern, wenn Sie einen der Dateitypen vermissen. Zum Beispiel haben Sie MP3, aber keine
EXE-Datei
2
Ich habe stderr nach / dev / null umgeleitet, um ls: *.exe: No such file or directoryzB Folgendes zu vermeiden :ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac
1
Wenn ich ls foo *. {Tar.gz, zip} direkt in einer Shell ausführe, funktioniert es, aber wenn dies in ein Shell-Skript eingefügt wird, ist last = $ (ls -I ' .done' -tr $ {pkgprefix} . {Tar. gz, zip} | tail -1) Ich habe eine Fehlermeldung erhalten: ls: kann nicht auf 'bamtools * zugreifen. {tar.gz, zip}': Keine solche Datei oder kein solches Verzeichnis, jeder klügere Typ kann die Antwort verfeinern.
Kemin Zhou
41

Verwenden Sie reguläre Ausdrücke mit find:

find . -iregex '.*\.\(mp3\|mp4\|exe\)' -printf '%f\n'

Wenn Sie die Dateinamen weiterleiten:

find . -iregex '.*\.\(mp3\|mp4\|exe\)' -printf '%f\0' | xargs -0 dosomething

Dies schützt Dateinamen, die Leerzeichen oder Zeilenumbrüche enthalten.

OS X findunterstützt den Wechsel nur, wenn die -E(erweiterte) Option verwendet wird.

find -E . -regex '.*\.(mp3|mp4|exe)'
Bis auf weiteres angehalten.
quelle
2
Unter Mac OS X:find . -iregex '.*\(mp3\|mp4\|exe\)'
Andilabs
3
andi, das hat bei mir auf mac os nicht funktioniert. Aber das tat: finde -E. -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson
Diese Lösung lädt Dateien wie: mysupermp3.jpg$\\.
Erwägen Sie
1
@ Pantro: Eigentlich wird es nicht. Find scheint implizite Anker zu verwenden. Der Punkt ist eine gute Idee (es wird nur ein Backslash benötigt).
Bis auf weiteres angehalten.
38

egrep - Extended Grep - wird hier helfen

ls | egrep '\.mp4$|\.mp3$|\.exe$'

sollte den Job machen.

Mob
quelle
Das ist es! Danke Ich habe gerade festgestellt, dass ich die Groß- und Kleinschreibung nicht berücksichtigen sollte, also verwende ich: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ Falls jemand anderes eines Tages Hilfe benötigt. Ich bin immer überrascht von der Geschwindigkeit, mit der ich hier meine Antwort bekomme.
Mint
Ich kann nicht sehen, wie das funktionieren würde. ls ohne Optionen erzeugt eine Ausgabe in Spalten. Die Verankerung am Ende der Linie stimmt nicht richtig überein.
Camh
4
@camh: lsan ein Terminal (oder mit -COption) erzeugt eine mehrspaltige Ausgabe. lszu einem Rohr (oder mit -1) hat eine einspaltige Ausgabe. (Ausgabe von lsmit vergleichen ls | cat).
Mob
Am Ende fehlt ein Apostroph. Davon abgesehen scheint es zu funktionieren.
Björn
12

Am einfachsten ist es, nur ls zu verwenden

ls *.mp4 *.mp3 *.exe
Joshua K.
quelle
2
Danke, aber ich habe das bereits versucht und die Fehler, die Sie erhalten, wenn keine Datei vorhanden ist, haben mir nicht gefallen. Du könntest das beheben, indem du tust: ls * .mp4 * .mp3 * .exe 2> / dev / null Ich dachte jetzt nur daran: P
Mint
1
Ich bin überrascht, dass lses keine stille Option gibt.
MitMaro
2
In Bash können Sie "set -o nullglob" ausführen, und Sie erhalten keine Fehler.
Camh
2
Mein Fehler - das sollte "shopt -s nullglob" sein, nicht der Befehl set -o
camh
1
Oder verwenden Sie einfach "echo": echo * .mp4 * .mp3 * .exe
Adrian Pronk
9

Nur für den Fall: Warum benutzt du nicht find?

find -iname '*.mp3' -o -iname '*.exe' -o -iname '*.mp4'
P Shved
quelle
Ich fand, dass dies stattdessen funktionierte - find . -name '*.mkv' -o -name '*.flv'(Hinzufügen von so vielen -o-Klauseln wie erforderlich). Ich brauchte das ., um das Verzeichnis und das Flag -namenicht anzugeben -iname- ich bin auf macOS 10.13.
Chris
6

Keine Notwendigkeit für grep. Shell-Platzhalter reichen aus.

ls *.mp4 *.mp3 *.exe

Wenn du gelaufen bist

shopt -s nullglob

dann werden nicht übereinstimmende Globs vollständig entfernt und nicht in der Befehlszeile nicht erweitert.

Wenn Sie ein Globbing ohne Berücksichtigung der Groß- und Kleinschreibung wünschen (daher entspricht * .mp3 foo.MP3):

shopt -s nocaseglob
camh
quelle
Gleicher Kommentar, den ich Good Time Tribe gegeben habe.
Mint
1
Ich versuche dies mit der -ROption zu verwenden, um übereinstimmende Dateien in Unterverzeichnissen aufzulisten, aber die Option scheint keine Auswirkung zu haben und ich erhalte immer noch nur die Ergebnisse des aktuellen Verzeichnisses.
Chris
3

Falls Sie noch nach einer alternativen Lösung suchen:

ls | grep -i -e '\\.tcl$' -e '\\.exe$' -e '\\.mp4$'

Fühlen Sie sich frei, bei Bedarf weitere -e-Flags hinzuzufügen.

Hai Vu
quelle
3

Für OSX-Benutzer :

Wenn Sie verwenden ls *.{mp3,exe,mp4}, wird ein Fehler ausgegeben, wenn eine dieser Erweiterungen keine Ergebnisse liefert.

Mit using ls *.(mp3|exe|mp4)werden alle Dateien zurückgegeben, die diesen Erweiterungen entsprechen, auch wenn eine der Erweiterungen 0 Ergebnisse hatte .

james2doyle
quelle
5
Ich habe einen Syntaxfehler anhand Ihres Beispiels erhalten. 'bash: Syntaxfehler in der Nähe eines unerwarteten Tokens' ('
Nagordon
2
Ich denke du meinst ls *.@(mp3|exe|mp4). Sie müssen shopt -s extglobdamit funktionieren. Ist übrigens auch lsnutzlos, könnte man einfach machen printf '%s\n' *.@(mp3|exe|mp4).
gniourf_gniourf
1
Ich bekomme die Syntax unerwartete Token-Nachricht auf macOS 10.13
Chris
1
ls | grep "\.mp4$
\.mp3$
\.exe$"
Jeff Mc
quelle
Danke, aber etwas unpraktisch, wenn mehrere Zeilen verbraucht werden.
Mint
Dies + mdfindliefert die besten / schnellsten Suchanfragen aller Zeiten! mdfind -name querystring | grep "\.h$" findet alle Header mit Quesrystring im Dateititel. pronto.
Alex Gray
1

ls -R | findstr ".mp3"

ls -R => listet Unterverzeichnisse rekursiv auf

vardamanpk
quelle
-1

Hier ist ein Beispiel, das für mich funktioniert hat.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
Jyoti Prakash
quelle