Você não precisa de nomes longos de caminho se você chdir
no diretório e apenas usar caminhos relativos para rmdir
.
Ou, se você tiver um shell POSIX instalado ou portar isso para o equivalente do DOS:
# untested code, didn't bother actually testing since the OP already solved the problem.
while [ -d Folder1 ]; do
mv Folder1/Folder1/Folder1/Folder1 tmp # repeat more times to work in larger batches
rm -r Folder1 # remove the first several levels remaining after moving the main tree out
# then repeat to end up with the remaining big tree under the original name
mv tmp/Folder1/Folder1/.../Folder1 Folder1
rm -r tmp
done
(Usar uma variável de shell para rastrear onde você a renomeou para a condição de loop é a outra alternativa para desenrolar o loop como eu fiz lá.)
Isso evita a sobrecarga da CPU da solução do KenD, que força o sistema operacional a percorrer a árvore do topo para o nível n
th sempre que um novo nível é adicionado, verificando permissões, etc. Portanto, ele tem sum(1, n) = n * (n-1) / 2 = O(n^2)
complexidade do tempo . As soluções que cortam um pedaço do início da cadeia devem ser O(n)
, a menos que o Windows precise atravessar uma árvore ao renomear seu diretório pai. (Linux / Unix não.) Soluções que chdir
até o final da árvore e usam caminhos relativos a partir daí, removendo diretórios como chdir
, também deve ser O(n)
, assumindo o O SO não precisa verificar todos os seus diretórios pai em todas as chamadas do sistema, quando você faz coisas enquanto está em algum lugar no CD.
find Folder1 -depth -execdir rmdir {} +
executará o rmdir enquanto estiver no CD com o diretório mais profundo. Ou, na verdade, a opção -delete
do find funciona em diretórios e implica em -depth
. Então find Folder1 -delete
deve fazer exatamente a mesma coisa, mas mais rápido. Sim, o GNU find no Linux desce varrendo um diretório, CDing para subdiretórios com caminhos relativos, então rmdir
com um caminho relativo, então chdir("..")
. Ele não faz uma nova varredura de diretórios durante a subida, então consumiria O(n)
RAM.
Isso foi realmente uma aproximação: strace
mostra que ele realmente usa unlinkat(AT_FDCWD, "tmp", AT_REMOVEDIR)
, open("..", O_DIRECTORY|...)
e fchdir(the fd from opening the directory)
, com um bocado de fstat
chamadas misturadas também. Mas o efeito é o mesmo se a árvore de diretórios não for modificada enquanto a localização está sendo executada.
edit: Apenas por brincadeira, eu tentei isso no GNU / Linux (Ubuntu 14.10, em uma CPU Core2Duo de primeira geração de 2.4GHz, em um sistema de arquivos XFS em uma unidade WD Power Green de 2,5 TB (WD25EZRS)).
time mkdir -p $(perl -e 'print "annoyingfoldername/" x 2000, "\n"')
real 0m1.141s
user 0m0.005s
sys 0m0.052s
find annoyingfoldername/ | wc
2000 2000 38019001 # 2k lines / 2k words / 38M characters of text
ll -R annoyingfoldername
... eventually
ls: cannot access ./annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername/annoyingfoldername: File name too long
total 0
?????????? ? ? ? ? ? annoyingfoldername
time find annoyingfoldername -delete
real 0m0.054s
user 0m0.004s
sys 0m0.049s
# about the same for normal rm -r,
# which also didn't fail due to long path names
(mkdir -p cria um diretório e qualquer componente do caminho ausente).
Sim, realmente 0,05 segundos para 2k rmdir ops. O xfs é muito bom em reunir as operações de metadados juntas no periódico, uma vez que elas consertaram as operações de metadados como 10 anos atrás.
No ext4, create levou 0m0.279s, delete com find ainda levou 0m0.074s.