Você não precisa de nomes de caminho longos se chdir
entrar no diretório e usar apenas caminhos relativos para rmdir
.
Ou, se você tiver um shell POSIX instalado, ou portá-lo 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 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 da KenD, que força o sistema operacional a atravessar a árvore do topo para o n
quinto nível toda vez que um novo nível é adicionado, verificando permissões etc. Por isso, possui sum(1, n) = n * (n-1) / 2 = O(n^2)
complexidade de tempo. As soluções que separam um pedaço do início da cadeia devem ser O(n)
, a menos que o Windows precise percorrer uma árvore ao renomear seu diretório pai. (Linux / Unix não.) Soluções que chdir
vão chdir
até a parte inferior da árvore e usam caminhos relativos a partir daí, removendo diretórios à medida que eles fazem backup, também devem ser O(n)
, assumindo que o sistema operacional não precise verificar todas as suas diretórios-pai a cada chamada do sistema, quando você faz coisas enquanto está em CD em algum lugar.
find Folder1 -depth -execdir rmdir {} +
executará o rmdir enquanto estiver em CD no diretório mais profundo. Ou, na verdade, a -delete
opção do find funciona em diretórios e implica -depth
. Então, find Folder1 -delete
deve fazer exatamente a mesma coisa, mas mais rápido. Sim, a localização do GNU no Linux desce, varrendo um diretório, colocando CD em subdiretórios com caminhos relativos e, em seguida, rmdir
com um caminho relativo chdir("..")
. Ele não verifica novamente os diretórios enquanto ascende, portanto consumiria O(n)
RAM.
Isso foi realmente uma aproximação: strace
mostra que realmente utiliza unlinkat(AT_FDCWD, "tmp", AT_REMOVEDIR)
, open("..", O_DIRECTORY|...)
e fchdir(the fd from opening the directory)
, com um monte de fstat
chamadas misturados também. Mas o efeito é o mesmo se a árvore de diretórios não for modificada enquanto a localização estiver em execução.
edit: Tentei fazer isso no GNU / Linux (Ubuntu 14.10, em uma CPU Core2Duo de primeira geração a 2,4 GHz, em um sistema de arquivos XFS em uma unidade WD 2.5TB Green Power (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 quaisquer componentes de caminho ausentes).
Sim, realmente 0,05 segundos para 2k rmdir ops. O xfs é muito bom em agrupar operações de metadados juntos no diário, uma vez que eles corrigiam operações de metadados sendo lentas como há 10 anos.
No ext4, a criação levou 0m0.279s, a exclusão com localização ainda levou 0m0.074s.
/MIR
:ROBOCOPY /MIR C:\temp\EmptyDirectory C:\Storage\Folder1
também pode valer a pena dar umachkdsk
risadinha.