Вам не нужны длинные пути, если вы находитесь chdir
в каталоге и просто используете относительные пути к rmdir
.
Или, если у вас установлена оболочка POSIX, или перенесите это на эквивалент 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
(Использование переменной оболочки для отслеживания того, где вы переименовали ее для условия цикла, является другой альтернативой развертыванию цикла, как я делал там.)
Это позволяет избежать перегрузки ЦП решения KenD, которая заставляет ОС обходить дерево с вершины до n
уровня th каждый раз, когда добавляется новый уровень, проверяя разрешения и т. Д. Таким образом, это sum(1, n) = n * (n-1) / 2 = O(n^2)
усложняет время. Должны быть решения, которые сокращают порцию с начала цепочки O(n)
, если только Windows не нужно обходить дерево при переименовании его родительского каталога. (Linux / Unix этого не делает.) Решения, которые chdir
вплоть до самого дна дерева и используют относительные пути оттуда, удаляя каталоги при их chdir
резервном копировании, также должны быть O(n)
при условии, что ОС не нужно проверять все ваши родительские каталоги каждый системный вызов, когда вы делаете что-то, когда CD-диск где-то.
find Folder1 -depth -execdir rmdir {} +
запустит rmdir, пока CDed в самый глубокий каталог. Или на самом деле -delete
опция find работает с каталогами и подразумевает -depth
. Так find Folder1 -delete
должно делать то же самое, но быстрее. Да, GNU находит в Linux спуск, сканируя каталог, CDing в подкаталоги с относительными путями, затем rmdir
с относительным путем, затем chdir("..")
. Он не пересканирует каталоги во время возрастания, поэтому он потребляет O(n)
оперативную память.
Это было действительно приближение: strace
показывает, что оно на самом деле использует unlinkat(AT_FDCWD, "tmp", AT_REMOVEDIR)
, open("..", O_DIRECTORY|...)
и fchdir(the fd from opening the directory)
с кучей fstat
вызовов тоже. Но эффект тот же, если дерево каталогов не изменяется, пока выполняется поиск.
редактировать: просто для удовольствия, я попробовал это на GNU / Linux (Ubuntu 14.10, на первом процессоре Core2Duo 2,4 ГГц, на файловой системе XFS на диске Green Power WD 2,5 ТБ (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 создает каталог и все отсутствующие компоненты пути).
Да, действительно 0,05 секунды для 2k rmdir ops. xfs неплохо умеет объединять операции метаданных в журнале, поскольку они исправляют медленные операции метаданных, как 10 лет назад.
На ext4 создание заняло 0m0.279s, удаление с поиском по-прежнему занимало 0m0.074s.
/MIR
вместо этого:ROBOCOPY /MIR C:\temp\EmptyDirectory C:\Storage\Folder1
также может стоить запуститьchkdsk
только для хихиканья.