Listar arquivos com certas extensões com ls e grep


152

Eu só quero obter os arquivos do diretório atual e apenas produzir arquivos .mp4 .mp3 .exe nada mais. Então eu pensei que poderia fazer isso:

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

Mas não, como o primeiro grep produzirá apenas mp4, portanto os outros 2 grep não serão usados.

Alguma ideia? PS, executando este script no Slow Leopard.


1
Essa é realmente a abordagem errada - em vez de usar grep, use shopt -s nullglobe apenas consulte *.exe *.mp3 *.mp4. Veja mywiki.wooledge.org/ParsingLs
Charles Duffy

1
Eu não consigo descobrir se ou não "Leopard lento" foi um erro de digitação ...
Wowfunhappy

1
@Wowfunhappy hahaha, definitivamente foi um erro de digitação, lembro-me de pensar que o Snow Leopard era bastante rápido.
Mint

Respostas:


335

Por que não:

ls *.{mp3,exe,mp4}

Não sei ao certo onde aprendi - mas estou usando isso.


1
Isso não está funcionando para mim porque a extensão que estou usando é para um diretório, portanto o ls está listando o conteúdo do diretório.
Richard Venable

1
@RichardVenable adicione a opção -d para impedir que os diretórios sejam recursivos.
Carlos Eugenio Thompson Pinzón

11
Eu gosto dessa solução, mas parece falhar se estiver faltando algum dos tipos de arquivo. Por exemplo, você tem mp3, mas não .exe (Mac OSX, zsh)
jho

2
I redirecionada stderr para / dev / null para evitar ls: *.exe: No such file or directory, por exemplo:ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac

1
Quando eu executo ls foo *. {Tar.gz, zip} diretamente em um shell, ele funciona, mas quando colocado dentro de um script shell mais recente = $ (ls -I ' .done' -tr $ {pkgprefix} . {Tar. gz, zip} | tail -1) Recebi uma mensagem de erro: ls: não é possível acessar 'bamtools *. {tar.gz, zip}': não existe esse arquivo ou diretório; qualquer pessoa mais inteligente pode refinar a resposta.
Kemin Zhou

41

Use expressões regulares com find:

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

Se você estiver canalizando os nomes dos arquivos:

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

Isso protege os nomes de arquivos que contêm espaços ou novas linhas.

O OS X findsuporta apenas alternância quando a -Eopção (aprimorada) é usada.

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

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

3
andi, isso não funcionou para mim no Mac OS. Mas isso aconteceu: encontre -E. -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson

Esta solução irá carregar arquivos como: mysupermp3.jpgconsiderar a adição da $no final da regex e \\.antes das extensões
Panthro

1
@ Panthro: na verdade, não vai. A localização parece usar âncoras implícitas. O ponto é uma boa ideia (apenas uma barra invertida é necessária).
Pausado até novo aviso.

38

egrep - grep estendido - ajudará aqui

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

deve fazer o trabalho.


É isso aí! Obrigado Acabei de perceber que eu deveria tê-lo em maiúsculas e minúsculas, então estou usando: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ Caso alguém precise de ajuda com isso um dia. Sempre fico surpreso com a velocidade em que recebo minha resposta aqui.
hortelã

Não vejo como isso funcionaria. ls sem nenhuma opção produz saída em colunas. A ancoragem no final da linha não será adequada.
CAMH

4
@camh: lspara um terminal (ou com -Copção) produz saída para várias colunas. lspara um tubo (ou com -1) possui saída de coluna única. (Compare a saída de lscom ls | cat).
turba

Há um apóstrofo ausente no final. Fora isso, parece funcionar.
Björn

12

a maneira mais fácil é usar ls

ls *.mp4 *.mp3 *.exe

2
Obrigado, mas eu já tentei isso e não gostei dos erros que você recebe quando não há arquivo. Tu que pude de fixo que, ao fazer: ls * .mp4 * .mp3 * .exe 2> / dev / null Só pensei nisso agora tu: P
Mint

1
Estou surpreso que lsnão tenha algum tipo de opção silenciosa.
MitMaro 19/09/09

2
No bash, você pode executar "set -o nullglob" e não obterá os erros.
CAMH

2
Meu erro - que deve ser "shopt -s nullglob" não o conjunto -o comando
CAMH

1
Ou simplesmente usar "echo": echo * .mp4 * .mp3 * .exe
Adrian Pronk

9

Apenas no caso: por que você não usa find?

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

Descobri que isso funcionava - find . -name '*.mkv' -o -name '*.flv'(adicionando quantas cláusulas -o, conforme necessário). Eu precisava .indicar o diretório e a bandeira -namenão -iname- estou no macOS 10.13.
13289 Chris

6

Não há necessidade de grep. Os curingas da Shell farão o truque.

ls *.mp4 *.mp3 *.exe

Se você correu

shopt -s nullglob

os globs incomparáveis ​​serão removidos por completo e não serão deixados na linha de comando sem expansão.

Se você deseja globbing sem distinção entre maiúsculas e minúsculas (então * .mp3 corresponderá a foo.MP3):

shopt -s nocaseglob

O mesmo comentário que dei à Good Time Tribe.
hortelã

1
Estou tentando usar isso com a -Ropção de listar arquivos correspondentes em subdiretórios, mas a opção parece não ter nenhum efeito e ainda recebo apenas os resultados do diretório atual.
Chris

3

Caso você ainda esteja procurando uma solução alternativa:

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

Sinta-se à vontade para adicionar mais sinalizadores -e, se necessário.


3

Para usuários OSX :

Se você usar ls *.{mp3,exe,mp4}, ocorrerá um erro se uma dessas extensões não tiver resultados.

O uso ls *.(mp3|exe|mp4)retornará todos os arquivos correspondentes a essas extensões, mesmo que uma delas tenha 0 resultados .


5
Eu recebi um erro de sintaxe usando o seu exemplo ??? 'bash: erro de sintaxe próximo ao token inesperado `('
nagordon 27/05

2
Eu acho que você quer dizer ls *.@(mp3|exe|mp4). Você precisa shopt -s extglobque isso funcione. By the way, lsé inútil também, você poderia apenas fazer printf '%s\n' *.@(mp3|exe|mp4).
Gnourf_gniourf

1
Recebo a mensagem de token inesperado da sintaxe no macOS 10.13
Chris

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

Obrigado, mas um pouco inconveniente, usando várias linhas.
hortelã

Este + mdfindproduz as melhores / pesquisas mais rápidas NUNCA! mdfind -name querystring | grep "\.h$" localiza todos os cabeçalhos com a consulta no título do arquivo. pronto.
Alex Gray

1

ls -R | findstr ".mp3"

ls -R => lista subdiretórios recursivamente


-1

Aqui está um exemplo que funcionou para mim.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.