Quero obter todos os nomes de arquivos de uma pasta usando Ruby.
358
Você também tem a opção de atalho de
Dir["/path/to/search/*"]
e se você deseja encontrar todos os arquivos Ruby em qualquer pasta ou subpasta:
Dir["/path/to/search/**/*.rb"]
./...
ao invés de~/
./
significa o diretório atual, enquanto que/
é o ponto de montagem raiz e~/
o diretório inicial do usuário. Se você mover o projeto inteiro para outro lugar, o primeiro funcionará, mas os outros dois provavelmente não.exemplo:
Fonte: http://ruby-doc.org/core/classes/Dir.html#method-c-entries
fonte
Dir#glob
poderia ter sido mencionado, por exemplo), não há nada para impedir que outra pessoa poste uma resposta realmente boa. 'Claro, eu sou mais um 'copo meio cheio' espécie de um cara ...Dir
raramente, e toda vez que preciso preciso ler a documentação. Postei minha pergunta e resposta aqui para encontrá-la mais tarde e talvez até ajudar alguém com a mesma pergunta. Acho que ouvi no podcast da SO que não há nada de errado com esse comportamento. Se você tiver uma resposta melhor, poste-a. Publiquei o que sei, não sou um ninja Ruby. Aceito regularmente respostas com mais votos.Dir[]
ouDir.glob
quando o argumento é uma variável. Quandopath = '/tmp'
, compare:Dir.glob("#{path}/*")
vsDir.entries(path)
. Os valores de retorno são um pouco diferentes (".", ".."), mas o último é mais fácil de entender rapidamente.Os seguintes trechos mostra exatamente o nome dos arquivos dentro de um diretório, subdiretórios pular e
"."
,".."
pastas pontilhadas:fonte
...select {|f| File.file? f}
para obter um significado mais claro e uma sintaxe mais curta.Dir.entries("your/folder").select {|f| File.file? f}
!File.directory?
está funcionando, masFile.file?
não está..reject {|f| File.directory? f}
parece mais limpo do que.select{|f| !File.directory? f}
. Ah, e agora eu vejo o primeiro comentário ... também é bom.Para obter todos os arquivos (somente arquivos estritamente) recursivamente:
Ou qualquer coisa que não seja um diretório (
File.file?
rejeitaria arquivos não regulares):Solução alternativa
Usar
Find#find
um método de pesquisa baseado em padrões comoDir.glob
é realmente melhor. Veja esta resposta em "Lista única para listar recursivamente diretórios em Ruby?" .fonte
Isso funciona para mim:
Se você não deseja arquivos ocultos [1], use Dir [] :
Agora, Dir.entries retornará arquivos ocultos e você não precisará do curinga asterix (basta passar a variável com o nome do diretório), mas retornará o nome da base diretamente, para que as funções File.xxx não funcionem .
[1]
.dotfile
no unix, eu não sei sobre o Windowsfonte
Agora, no Ruby 2.5, você pode usar
Dir.children
. Ele obtém nomes de arquivos como uma matriz, exceto por "." e ".."Exemplo:
http://ruby-doc.org/core-2.5.0/Dir.html#method-c-children
fonte
Pessoalmente, achei isso o mais útil para fazer loop sobre arquivos em uma pasta, com segurança no futuro:
fonte
Esta é uma solução para encontrar arquivos em um diretório:
fonte
Ao obter todos os nomes de arquivo em um diretório, esse trecho pode ser usado para rejeitar os diretórios [
.
,..
] e os arquivos ocultos que começam com um.
fonte
Dir.entries
retorna nomes de arquivos locais, não caminhos de arquivo absolutos. Por outro lado,File.directory?
espera um caminho de arquivo absoluto. Este código não funciona conforme o esperado.esse código retorna apenas nomes de arquivos com sua extensão (sem um caminho global)
fonte
Isto é o que funciona para mim:
Dir.entries
retorna uma matriz de seqüências de caracteres. Então, temos que fornecer um caminho completo do arquivo paraFile.file?
, a menos quedir
seja igual ao nosso diretório de trabalho atual. É por isso que issoFile.join()
.fonte
Você também pode querer usar
Rake::FileList
(desde que tenharake
dependência):De acordo com a API:
https://docs.ruby-lang.org/en/2.1.0/Rake/FileList.html
fonte
Se você deseja obter uma variedade de nomes de arquivos, incluindo links simbólicos , use
ou mesmo
e se você quiser ficar sem links simbólicos , use
Conforme mostrado em outras respostas, use em
Dir.glob('/path/to/dir/**/*')
vez deDir.new('/path/to/dir')
se desejar obter todos os arquivos recursivamente.fonte
*.*
fonte
Além das sugestões neste tópico, eu gostaria de mencionar que, se você também precisar retornar arquivos de ponto (.gitignore, etc), com o Dir.glob, será necessário incluir um sinalizador da seguinte maneira:
Dir.glob("/path/to/dir/*", File::FNM_DOTMATCH)
Por padrão, Dir.entries inclui arquivos de ponto, bem como os diretórios pai atuais.Para qualquer pessoa interessada, fiquei curioso para saber como as respostas aqui se comparavam em tempo de execução, eis os resultados contra uma hierarquia profundamente aninhada. Os três primeiros resultados são não recursivos:
Eles foram gerados com o seguinte script de benchmarking:
As diferenças nas contagens de arquivos são devidas à
Dir.entries
inclusão de arquivos ocultos por padrão.Dir.entries
acabou demorando um pouco mais nesse caso, devido à necessidade de reconstruir o caminho absoluto do arquivo para determinar se um arquivo era um diretório, mas mesmo assim ele ainda estava demorando consistentemente mais do que as outras opções no caso recursivo. Isso tudo estava usando o ruby 2.5.1 no OSX.fonte
Uma maneira simples pode ser:
fonte
retorna os caminhos relativos do arquivo do diretório e de todos os subdiretórios
fonte
Em um contexto de IRB, você pode usar o seguinte para obter os arquivos no diretório atual:
Você também pode fazer isso funcionar em outros diretórios:
fonte