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.

hortelã
fonte
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.

meder omuraliev
fonte
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)'
Pausado até novo aviso.
fonte
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.

multidão
fonte
É 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
Joshua K
fonte
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'
P Shved
fonte
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
camh
fonte
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.

Hai Vu
fonte
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 .

james2doyle
fonte
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$"
Jeff Mc
fonte
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

vardamanpk
fonte
-1

Aqui está um exemplo que funcionou para mim.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
Jyoti Prakash
fonte