Lister les fichiers avec certaines extensions avec ls et grep


153

Je veux juste obtenir les fichiers du répertoire actuel et ne sortir que les fichiers .mp4 .mp3 .exe rien d'autre. Alors j'ai pensé que je pouvais simplement faire ceci:

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

Mais non, comme le premier grep ne sortira que des mp4, les 2 autres grep ne seront pas utilisés.

Des idées? PS, Exécution de ce script sur Slow Leopard.


1
C'est vraiment la mauvaise approche - au lieu d'utiliser grep, utilisez shopt -s nullglob, puis faites simplement référence à *.exe *.mp3 *.mp4. Voir mywiki.wooledge.org/ParsingLs
Charles Duffy

1
Je ne peux pas comprendre si "Slow Leopard" était une faute de frappe ...
Wowfunhappy

1
@Wowfunhappy hahaha, c'était définitivement une faute de frappe, je me souviens avoir pensé que Snow Leopard était assez rapide.
État neuf

Réponses:


336

Pourquoi pas:

ls *.{mp3,exe,mp4}

Je ne sais pas où je l'ai appris - mais je l'utilise.


1
Cela ne fonctionne pas pour moi car l'extension que j'utilise est pour un répertoire, donc le ls répertorie le contenu du répertoire.
Richard Venable

1
@RichardVenable ajoutez le commutateur -d pour empêcher que les répertoires ne soient récurrents.
Carlos Eugenio Thompson Pinzón

11
J'aime cette solution mais elle semble échouer s'il vous manque l'un des types de fichiers. Par exemple, vous avez des mp3 mais pas de .exe (Mac OSX, zsh)
JHo

2
J'ai redirigé stderr vers / dev / null pour éviter ls: *.exe: No such file or directorypar exemple:ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac le

1
Quand je lance ls foo *. {Tar.gz, zip} directement dans un shell, cela fonctionne, mais quand je le mets dans un script shell latest = $ (ls -I ' .done' -tr $ {pkgprefix} . {Tar. gz, zip} | tail -1) J'ai reçu un message d'erreur: ls: impossible d'accéder à 'bamtools *. {tar.gz, zip}': Aucun fichier ou répertoire de ce type, tout homme plus intelligent peut affiner la réponse.
Kemin Zhou

41

Utilisez des expressions régulières avec find:

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

Si vous transmettez les noms de fichiers:

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

Cela protège les noms de fichiers contenant des espaces ou des retours à la ligne.

OS X findne prend en charge l'alternance que lorsque l' -Eoption (améliorée) est utilisée.

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

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

3
andi, cela n'a pas fonctionné pour moi sur mac os. Mais ceci a fait: trouver -E. -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson

Cette solution chargera des fichiers comme: mysupermp3.jpgpensez à ajouter le $à la fin de l'expression régulière et le \\.avant les extensions
Panthro

1
@Panthro: en fait, ce ne sera pas le cas. Find semble utiliser des ancres implicites. Le point est une bonne idée (une seule barre oblique inverse est nécessaire).
Suspendu jusqu'à nouvel ordre.

39

egrep - grep étendu - aidera ici

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

devrait faire le travail.


C'est tout! Merci Je viens de réaliser que je devrais l'avoir insensible à la casse, alors j'utilise: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ Au cas où quelqu'un d'autre aurait besoin d'aide pour cela un jour. Je suis toujours surpris par la rapidité avec laquelle je reçois ma réponse ici.
Neuf

Je ne vois pas comment cela fonctionnerait. ls sans aucune option produit une sortie en colonnes. L'ancrage à la fin de la ligne ne correspondra pas correctement.
camh le

4
@camh: lsvers un terminal (ou avec -Coption) produit une sortie multi-colonnes. lsvers un tube (ou avec -1) a une sortie de colonne unique. (Comparez la sortie de lsavec ls | cat).
mob le

Il y a une apostrophe manquante à la fin. A part cela, cela semble fonctionner.
Björn

12

le moyen le plus simple est d'utiliser simplement ls

ls *.mp4 *.mp3 *.exe

2
Merci, mais j'ai déjà essayé et je n'ai pas aimé les erreurs que vous obtenez quand il n'y a pas de fichier. Tu pourrais réparer ça en faisant: ls * .mp4 * .mp3 * .exe 2> / dev / null Je n'y ai pensé que maintenant tu: P
Neuf

1
Je suis surpris qu'il lsn'y ait pas d'option silencieuse.
MitMaro

2
Dans bash, vous pouvez faire "set -o nullglob", et vous n'obtiendrez pas les erreurs.
camh

2
Mon erreur - cela devrait être "shopt -s nullglob" et non la commande set -o
camh

1
Ou utilisez simplement "echo": echo * .mp4 * .mp3 * .exe
Adrian Pronk

9

Juste au cas où: pourquoi ne pas utiliser find?

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

J'ai trouvé que cela fonctionnait à la place - find . -name '*.mkv' -o -name '*.flv'(en ajoutant autant de clauses -o que nécessaire). Je avais besoin .pour indiquer le répertoire et le drapeau -namepas -iname- je suis sur macOS 10,13.
Chris

6

Pas besoin de grep. Les jokers Shell feront l'affaire.

ls *.mp4 *.mp3 *.exe

Si vous avez couru

shopt -s nullglob

alors les globes sans correspondance seront complètement supprimés et ne seront pas laissés sur la ligne de commande sans développement.

Si vous voulez un globbing insensible à la casse (donc * .mp3 correspondra à foo.MP3):

shopt -s nocaseglob

Même commentaire que j'ai fait à Good Time Tribe.
Neuf

1
J'essaie de l'utiliser avec l' -Roption de lister les fichiers correspondants dans les sous-répertoires mais l'option ne semble pas avoir d'effet et je n'obtiens toujours que les résultats du répertoire actuel.
Chris

3

Dans le cas où vous êtes toujours à la recherche d'une solution alternative:

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

N'hésitez pas à ajouter d'autres indicateurs -e si nécessaire.


3

Pour les utilisateurs OSX :

Si vous utilisez ls *.{mp3,exe,mp4}, cela générera une erreur si l'une de ces extensions n'a pas de résultats.

L'utilisation ls *.(mp3|exe|mp4)retournera tous les fichiers correspondant à ces extensions, même si l'une des extensions n'a donné aucun résultat .


5
J'ai eu une erreur de syntaxe en utilisant votre exemple ??? 'bash: erreur de syntaxe près de jeton inattendu `('
nagordon

2
Je suppose que tu veux dire ls *.@(mp3|exe|mp4). Vous en avez besoin shopt -s extglobpour que cela fonctionne. En passant, lsest inutile aussi, vous pouvez le faire printf '%s\n' *.@(mp3|exe|mp4).
gniourf_gniourf

1
Je reçois le message de jeton inattendu de syntaxe sur macOS 10.13
Chris

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

Merci, mais un peu gênant en utilisant plusieurs lignes.
Neuf

Ceci + mdfindproduit les recherches les meilleures / les plus rapides JAMAIS! mdfind -name querystring | grep "\.h$" trouve tous les en-têtes avec quesrystring dans le titre du fichier. pronto.
Alex Gray

1

ls -R | findstr ".mp3"

ls -R => liste les sous-répertoires de manière récursive


-1

Voici un exemple qui a fonctionné pour moi.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.