Lista de archivos con ciertas extensiones con ls y grep


153

Solo quiero obtener los archivos del directorio actual y solo generar archivos .mp4 .mp3 .exe nada más. Entonces pensé que podría hacer esto:

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

Pero no, ya que el primer grep generará solo mp4, por lo tanto, los otros 2 grep no se utilizarán.

¿Algunas ideas? PD: Ejecutar este script en Slow Leopard.


1
Este es realmente el enfoque equivocado: en lugar de usar grep, use shopt -s nullgloby luego simplemente consulte *.exe *.mp3 *.mp4. Ver mywiki.wooledge.org/ParsingLs
Charles Duffy

1
No puedo entender si "Slow Leopard" fue un error tipográfico ...
Wowfunhappy

1
@Wowfunhappy jajaja, definitivamente fue un error tipográfico, recuerdo haber pensado que Snow Leopard fue bastante rápido.
Menta

Respuestas:


336

Por qué no:

ls *.{mp3,exe,mp4}

No estoy seguro de dónde lo aprendí, pero he estado usando esto.


1
Esto no funciona para mí porque la extensión que estoy usando es para un directorio, por lo que ls enumera el contenido del directorio.
Richard Venable

1
@RichardVenable agregue el modificador -d para evitar que se repitan los directorios.
Carlos Eugenio Thompson Pinzón

11
Me gusta esta solución, pero parece fallar si te falta alguno de los tipos de archivo. Por ejemplo, tiene mp3 pero no .exe (Mac OSX, zsh)
JHo

2
Redirigí stderr a / dev / null para evitar, ls: *.exe: No such file or directorypor ejemplo:ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac

1
Cuando ejecuto ls foo *. {Tar.gz, zip} directamente en un shell, funciona, pero cuando lo coloco dentro de un script de shell latest = $ (ls -I ' .done' -tr $ {pkgprefix} . { Tar . gz, zip} | tail -1) Recibí un mensaje de error: ls: no puedo acceder a 'bamtools *. {tar.gz, zip}': No existe tal archivo o directorio, cualquier tipo más inteligente puede refinar la respuesta.
Kemin Zhou

41

Use expresiones regulares con find:

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

Si está canalizando los nombres de archivo:

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

Esto protege los nombres de archivos que contienen espacios o nuevas líneas.

OS X findsolo admite alternancia cuando -Ese usa la opción (mejorada).

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

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

3
andi, eso no funcionó para mí en mac os. Pero esto sí: encuentra -E. -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson el

Esta solución cargará archivos como: mysupermp3.jpgconsidere agregar $al final de la expresión regular y \\.antes de las extensiones
Panthro

1
@Panthro: en realidad, no lo hará. Buscar parece usar anclajes implícitos. El punto es una buena idea (solo se necesita una barra invertida).
Pausado hasta nuevo aviso.

39

egrep - grep extendido - ayudará aquí

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

Debería hacer el trabajo.


¡Eso es! Gracias Acabo de darme cuenta de que debería tener mayúsculas y minúsculas, así que estoy usando: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ En caso de que alguien más necesite ayuda con eso algún día. Siempre estoy sorprendido por la velocidad que obtengo mi respuesta aquí.
Menta

No puedo ver cómo funcionaría esto. ls sin ninguna opción produce resultados en columnas. El anclaje al final de la línea no coincidirá correctamente.
camh

44
@camh: lsa un terminal (o con -Copción) produce una salida de varias columnas. lsa una tubería (o con -1) tiene salida de columna única. (Comparar salida de lscon ls | cat).
mob

Falta un apóstrofe al final. Aparte de eso, parece funcionar.
Björn

12

la forma más fácil es usar ls

ls *.mp4 *.mp3 *.exe

2
Gracias, pero ya lo intenté y no me gustaron los errores que aparece cuando no hay un archivo. Podrías haberlo arreglado haciendo: ls * .mp4 * .mp3 * .exe 2> / dev / null Solo pensé en eso ahora: P
Mint

1
Me sorprende que lsno tenga algún tipo de opción silenciosa.
MitMaro

2
En bash, puede hacer "set -o nullglob" y no obtendrá los errores.
camh

2
Mi error - eso debería ser "shopt -s nullglob" no el comando set -o
camh

1
O simplemente use "echo": echo * .mp4 * .mp3 * .exe
Adrian Pronk

9

Por si acaso: ¿por qué no lo usas find?

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

En su lugar, esto funcionó - find . -name '*.mkv' -o -name '*.flv'(agregando tantas cláusulas -o como sea necesario). Necesitaba el .para indicar el directorio y el indicador -nameno -iname, estoy en macOS 10.13.
Chris

6

No hay necesidad de grep. Los comodines de Shell harán el truco.

ls *.mp4 *.mp3 *.exe

Si has corrido

shopt -s nullglob

entonces los globos no coincidentes se eliminarán por completo y no se dejarán en la línea de comando sin expandir.

Si desea un globbing que no distinga entre mayúsculas y minúsculas (entonces * .mp3 coincidirá con foo.MP3):

shopt -s nocaseglob

El mismo comentario que le di a Good Time Tribe.
Menta

1
Estoy tratando de usar esto con la -Ropción de enumerar archivos coincidentes en subdirectorios, pero la opción no parece tener ningún efecto y todavía solo obtengo los resultados del directorio actual.
Chris

3

En caso de que todavía esté buscando una solución alternativa:

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

Siéntase libre de agregar más banderas -e si es necesario.


3

Para usuarios de OSX :

Si lo usa ls *.{mp3,exe,mp4}, arrojará un error si una de esas extensiones no tiene resultados.

El uso ls *.(mp3|exe|mp4)devolverá todos los archivos que coincidan con esas extensiones, incluso si una de las extensiones tuvo 0 resultados .


55
¿Recibí un error de sintaxis con tu ejemplo? 'bash: error de sintaxis cerca de token inesperado' ('
nagordon

2
Supongo que te refieres ls *.@(mp3|exe|mp4). Necesitas shopt -s extglobque esto funcione. Por cierto, también lses inútil, simplemente podrías hacerlo printf '%s\n' *.@(mp3|exe|mp4).
gniourf_gniourf

1
Recibo el mensaje de token inesperado de sintaxis en macOS 10.13
Chris

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

Gracias, pero un poco incómodo usando varias líneas.
Menta

¡Esto + mdfindproduce las mejores / más rápidas búsquedas NUNCA! mdfind -name querystring | grep "\.h$" encuentra todos los encabezados con quesrystring en el título del archivo. pronto.
Alex Gray

1

ls -R | findstr ".mp3"

ls -R => enumera subdirectorios de forma recursiva


-1

Aquí hay un ejemplo que funcionó para mí.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.