Elenca i file con determinate estensioni con ls e grep


153

Voglio solo ottenere i file dalla directory corrente e produrre solo file .mp4 .mp3 .exe nient'altro. Quindi ho pensato di poter fare solo questo:

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

Ma no, dato che il primo grep produrrà solo gli MP4, per cui gli altri 2 grep non verranno utilizzati.

Qualche idea? PS, eseguendo questo script su Slow Leopard.


1
Questo è davvero l'approccio sbagliato - invece di usare grep, usa shopt -s nullglobe poi fai riferimento *.exe *.mp3 *.mp4. Vedi mywiki.wooledge.org/ParsingLs
Charles Duffy,

1
Non riesco a capire se "Slow Leopard" fosse o no un refuso ...
Wowfunhappy,

1
@Wowfunhappy hahaha, sicuramente era un errore di battitura, ricordo che pensavo che Snow Leopard fosse abbastanza veloce.
Menta,

Risposte:


336

Perchè no:

ls *.{mp3,exe,mp4}

Non sono sicuro di dove l'ho imparato, ma lo sto usando.


1
Questo non funziona per me perché l'estensione che sto usando è per una directory, quindi ls sta elencando il contenuto della directory.
Richard Venable,

1
@RichardVenable aggiungere l'opzione -d per impedire che le directory vengano ripetute.
Carlos Eugenio Thompson Pinzón,

11
Mi piace questa soluzione ma sembra fallire se ti manca uno dei tipi di file. Ad esempio, hai mp3 ma non .exe (Mac OSX, zsh)
JHo

2
Ho reindirizzato stderr a / dev / null per evitare ls: *.exe: No such file or directoryad esempio:ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac il

1
Quando eseguo ls foo *. {Tar.gz, zip} direttamente in una shell funziona, ma quando lo inserisco in uno script della shell latest = $ (ls -I '.done' -tr $ {pkgprefix} . {Tar. gz, zip} | tail -1) Ho ricevuto un messaggio di errore: ls: impossibile accedere a "bamtools *. {tar.gz, zip}": nessun file o directory, nessun ragazzo più intelligente può perfezionare la risposta.
Kemin Zhou,

41

Usa le espressioni regolari con find:

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

Se stai eseguendo il piping dei nomi dei file:

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

Questo protegge i nomi dei file che contengono spazi o nuove righe.

OS X findsupporta l'alternanza solo quando -Esi utilizza l'opzione (potenziata).

find -E . -regex '.*\.(mp3|mp4|exe)'

2
Su Mac OS X:find . -iregex '.*\(mp3\|mp4\|exe\)'
andilab

3
andi, non ha funzionato per me su mac os. Ma questo ha fatto: trova -E. -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson,

Questa soluzione caricherà file come: mysupermp3.jpgconsidera l'aggiunta $alla fine del regex e la \\.prima delle estensioni
Panthro

1
@Panthro: in realtà no. Trova sembra utilizzare ancore implicite. Il punto è una buona idea (è necessaria solo una barra rovesciata).
In pausa fino a nuovo avviso.

39

egrep - grep esteso - aiuterà qui

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

dovrebbe fare il lavoro.


Questo è tutto! Grazie Ho appena realizzato che avrei dovuto distinguere tra maiuscole e minuscole, quindi sto usando: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ Nel caso in cui un giorno qualcuno avesse bisogno di aiuto. Sono sempre sorpreso dalla velocità con cui ottengo la mia risposta qui.
Menta,

Non riesco a vedere come funzionerebbe. Senza alcuna opzione produce output in colonne. L'ancoraggio alla fine della linea non corrisponderà correttamente.
Camh,

4
@camh: lsa un terminale (o con -Copzione) produce output multi-colonna. lsa una pipe (o con -1) ha un output a colonna singola. (Confronta l'output di lscon ls | cat).
mob,

C'è un apostrofo mancante alla fine. A parte questo sembra funzionare.
Björn,

12

il modo più semplice è usare semplicemente ls

ls *.mp4 *.mp3 *.exe

2
Grazie, ma l'ho già provato e non mi sono piaciuti gli errori che ricevi quando non ci sono file. Potrei risolverlo facendo: ls * .mp4 * .mp3 * .exe 2> / dev / null Ho pensato solo a quello ora: P
Menta

1
Sono sorpreso che lsnon abbia una sorta di opzione silenziosa.
MitMaro,

2
In bash, puoi fare "set -o nullglob" e non otterrai errori.
Camh,

2
Il mio errore - dovrebbe essere "shopt -s nullglob" non il comando set -o
camh,

1
O semplicemente usa "echo": echo * .mp4 * .mp3 * .exe
Adrian Pronk,

9

Per ogni evenienza: perché non usi find?

find -iname '*.mp3' -o -iname '*.exe' -o -iname '*.mp4'

Ho trovato che invece ha funzionato - find . -name '*.mkv' -o -name '*.flv'(aggiungendo tutte le clausole -o necessarie). Avevo bisogno .di indicare la directory e il flag -nameno -iname- sono su macOS 10.13.
Chris,

6

Non c'è bisogno di grep. I jolly Shell faranno il trucco.

ls *.mp4 *.mp3 *.exe

Se hai corso

shopt -s nullglob

quindi i globs senza pari verranno rimossi del tutto e non verranno lasciati sulla riga di comando non espansi.

Se vuoi il globbing senza distinzione tra maiuscole e minuscole (quindi * .mp3 corrisponderà a foo.MP3):

shopt -s nocaseglob

Stesso commento che ho dato a Good Time Tribe.
Menta,

1
Sto cercando di usarlo con l' -Ropzione per elencare i file corrispondenti nelle sottodirectory ma l'opzione non sembra avere alcun effetto e ottengo solo i risultati della directory corrente.
Chris,

3

Se stai ancora cercando una soluzione alternativa:

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

Sentiti libero di aggiungere più -e flag se necessario.


3

Per utenti OSX :

Se lo usi ls *.{mp3,exe,mp4}, genererà un errore se una di quelle estensioni non ha risultati.

L'utilizzo ls *.(mp3|exe|mp4)restituirà tutti i file corrispondenti a tali estensioni, anche se una delle estensioni ha ottenuto 0 risultati .


5
Ho avuto un errore di sintassi usando il tuo esempio ??? 'bash: errore di sintassi vicino token inaspettato' ('
nagordon

2
Immagino tu intenda ls *.@(mp3|exe|mp4). È necessario shopt -s extglobche funzioni. A proposito, lsè anche inutile, potresti semplicemente fare printf '%s\n' *.@(mp3|exe|mp4).
gniourf_gniourf

1
Ricevo il messaggio di token imprevisto della sintassi su macOS 10.13
Chris,

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

Grazie, ma un po 'scomodo usare più righe.
Menta,

Questo + mdfindproduce le ricerche migliori / più veloci MAI! mdfind -name querystring | grep "\.h$" trova tutte le intestazioni con quesrystring nel titolo del file. Pronto.
Alex Gray,

1

ls -R | findstr ".mp3"

ls -R => elenca le sottodirectory ricorsivamente


-1

Ecco un esempio che ha funzionato per me.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.