Eu tenho um plano de fundo em C ++ / Obj-C e estou apenas descobrindo o Python (estou escrevendo há cerca de uma hora). Estou escrevendo um script para ler recursivamente o conteúdo de arquivos de texto em uma estrutura de pastas.
O problema que tenho é o código que escrevi funcionará apenas para uma pasta em profundidade. Eu posso ver por que, no código (veja #hardcoded path
), simplesmente não sei como posso avançar com o Python, pois minha experiência com ele é apenas nova.
Código Python:
import os
import sys
rootdir = sys.argv[1]
for root, subFolders, files in os.walk(rootdir):
for folder in subFolders:
outfileName = rootdir + "/" + folder + "/py-outfile.txt" # hardcoded path
folderOut = open( outfileName, 'w' )
print "outfileName is " + outfileName
for file in files:
filePath = rootdir + '/' + file
f = open( filePath, 'r' )
toWrite = f.read()
print "Writing '" + toWrite + "' to" + filePath
folderOut.write( toWrite )
f.close()
folderOut.close()
os.walk
não é ruim, embora eu tenha pensado em uma maneira ainda mais rápidaos.scandir
. Todas asglob
soluções são muito mais lentas que owalk
&scandir
. Minha função, bem como uma análise completa da velocidade, podem ser encontradas aqui: stackoverflow.com/a/59803793/2441026Se você estiver usando o Python 3.5 ou superior, poderá fazer isso em 1 linha.
Conforme mencionado na documentação
Se você quiser todos os arquivos, poderá usar
fonte
root_dir
precisa de uma barra final? Isso economizará tempo das pessoas (ou pelo menos teria me economizado tempo). Obrigado.glob.iglob(root_dir + '**/**', recursive=True)
. Estou trabalhando em Python 3.8.2Concordo com Dave Webb,
os.walk
produzirá um item para cada diretório da árvore. O fato é que você simplesmente não precisa se preocuparsubFolders
.Código como este deve funcionar:
fonte
TL; DR: é o equivalente a
find -type f
examinar todos os arquivos em todas as pastas abaixo e incluindo o atual:Como já mencionado em outras respostas,
os.walk()
é a resposta, mas poderia ser melhor explicada. É bem simples! Vamos andar por esta árvore:Com este código:
A
currentpath
é a pasta atual para a qual está olhando. Isso produzirá:Então ele executa um loop três vezes, porque existem três pastas: a atual,,
docs
epics
. Em cada loop, ele preenche as variáveisfolders
efiles
com todas as pastas e arquivos. Vamos mostrar a eles:Isso nos mostra:
Assim, na primeira linha, vemos que estamos em pasta
.
, que contém duas pastas ou seja,pics
edocs
, e que há um arquivo, ou sejatodo.txt
. Você não precisa fazer nada para recolocar nessas pastas, porque, como vê, ele se repete automaticamente e apenas fornece os arquivos em todas as subpastas. E qualquer subpasta disso (embora não tenhamos as do exemplo).Se você deseja apenas percorrer todos os arquivos, o equivalente a
find -type f
, você pode fazer isso:Isso gera:
fonte
A
pathlib
biblioteca é realmente ótima para trabalhar com arquivos. Você pode fazer um globo recursivo em umPath
objeto como esse.fonte
Se você deseja uma lista simples de todos os caminhos em um determinado diretório (como
find .
no shell):Para incluir apenas caminhos completos para arquivos sob o diretório base, deixe de fora
+ subdirs
.fonte
**/**
é usado para obter todos os arquivos recursivamente, incluindodirectory
.if os.path.isfile(filename)
é usado para verificar se afilename
variável éfile
oudirectory
, se é um arquivo, podemos ler esse arquivo. Aqui estou imprimindo arquivo.fonte
Eu achei o seguinte o mais fácil
Usar
glob('some/path/**', recursive=True)
obtém todos os arquivos, mas também inclui nomes de diretório. A adição daif os.path.isfile(f)
condição filtra esta lista apenas aos arquivos existentesfonte
use
os.path.join()
para construir seus caminhos - é mais limpo:fonte
os.walk
faz caminhada recursiva por padrão. Para cada dir, a partir do raiz, produz três tuplas (caminho de diretório, nomes de diretórios, nomes de arquivos)fonte
walk()
, retorne lista recursiva. Eu tentei o seu código e tem uma lista com muitas repetições ... Se você simplesmente remover linhas sob o comentário "# chamadas recursivas em subpastas" - ele funciona muito bemTente o seguinte:
fonte
Acho que o problema é que você não está processando a saída
os.walk
corretamente.Primeiro, mude:
para:
rootdir
é seu diretório inicial fixo;root
é um diretório retornado poros.walk
.Em segundo lugar, você não precisa recuar seu loop de processamento de arquivos, pois não faz sentido executá-lo para cada subdiretório. Você será
root
definido para cada subdiretório. Você não precisa processar os subdiretórios manualmente, a menos que queira fazer algo com os próprios diretórios.fonte
filePath = rootdir + '/' + file
, isso não parece certo: o arquivo é da lista de arquivos atuais, então você está gravando para muitos arquivos existentes?