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.