Nie potrzebujesz długich nazw ścieżek, jeśli wchodzisz chdir
do katalogu i po prostu używasz ścieżek względnych do rmdir
.
Lub, jeśli masz zainstalowaną powłokę POSIX lub przenieś ją do odpowiednika 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
(Użycie zmiennej powłoki do śledzenia miejsca, w którym została zmieniona jej nazwa dla warunku pętli, jest inną alternatywą dla rozwijania pętli, jak tam.)
Pozwala to uniknąć obciążenia procesora przez rozwiązanie KenD, które zmusza system operacyjny do przechodzenia przez drzewo od góry do n
poziomu th za każdym razem, gdy dodawany jest nowy poziom, sprawdzania uprawnień itp. Ma więc sum(1, n) = n * (n-1) / 2 = O(n^2)
złożoność czasową. Powinny istnieć rozwiązania, które oddzielają fragment od początku łańcucha O(n)
, chyba że system Windows musi przejść przez drzewo podczas zmiany nazwy katalogu nadrzędnego. (Linux / Unix nie.) Rozwiązania, chdir
które chdir
sięgają do samego końca drzewa i używają stamtąd ścieżek względnych, usuwając katalogi podczas tworzenia kopii zapasowej, powinny również być O(n)
, zakładając, że system operacyjny nie musi sprawdzać wszystkich katalogi nadrzędne każde wywołanie systemowe, gdy robisz coś, gdy gdzieś jest CD.
find Folder1 -depth -execdir rmdir {} +
uruchomi rmdir podczas zapisywania CD do najgłębszego katalogu. A właściwie -delete
opcja find działa na katalogach i implikuje -depth
. find Folder1 -delete
Powinien więc zrobić dokładnie to samo, ale szybciej. Tak, GNU find w Linuksie schodzi przez skanowanie katalogu, CDing do podkatalogów ze ścieżkami względnymi, a następnie rmdir
ścieżką względną chdir("..")
. Nie skanuje ponownie katalogów podczas wstępowania, więc zużywa O(n)
pamięć RAM.
To było naprawdę przybliżenie: strace
pokazy faktycznie korzysta unlinkat(AT_FDCWD, "tmp", AT_REMOVEDIR)
, open("..", O_DIRECTORY|...)
oraz fchdir(the fd from opening the directory)
z grupą fstat
połączeń mieszane, też. Ale efekt jest taki sam, jeśli drzewo katalogów nie jest modyfikowane podczas działania funkcji find.
edycja: Tylko dla kopnięć próbowałem tego na GNU / Linux (Ubuntu 14.10, na pierwszej generacji procesorze Core2Duo pierwszej generacji 2,4 GHz, na systemie plików XFS na dysku 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 tworzy katalog i wszelkie brakujące elementy ścieżki).
Tak, naprawdę 0,05 sekundy na 2k rmdir ops. xfs jest całkiem dobry w grupowaniu operacji na metadanych w czasopiśmie, ponieważ naprawiono powolne operacje metadanych, jak 10 lat temu.
Na ext4 tworzenie zajęło 0m0,279s, usunięcie z szukaniem wciąż zajęło 0m0,074s.
/MIR
zamiast tego:ROBOCOPY /MIR C:\temp\EmptyDirectory C:\Storage\Folder1
być może warto uruchomićchkdsk
tylko na chichoty.