Эффективное удаление большого каталога, содержащего тысячи файлов

У нас проблема с папкой, которая становится громоздкой с сотнями тысяч крошечных файлов.

Существует так много файлов, что выполнение rm -rf возвращает ошибку, и вместо этого нам нужно что-то вроде:

find /path/to/folder -name "filenamestart*" -type f -exec rm -f {} \;

Это работает, но очень медленно и постоянно выходит из строя из-за нехватки памяти.

Есть лучший способ сделать это? В идеале я хотел бы удалить весь каталог, не заботясь о содержимом внутри него.

  • Удаление пустого файла, почему так много вызовов sys?
  • Rm -rf * рекурсивно удаляет файлы из текущего каталога или родительского / корневого каталога?
  • Как удалить все файлы в текущем каталоге за исключением последних двух
  • удаление «файла» в / proc или / dev
  • Как удалить каталоги на основе вывода `find`?
  • grep string из содержимого команды file, а затем удалить файл
  • команды оболочки для проверки и создания директории
  • Как заставить создать символическую ссылку?
  • 14 Solutions collect form web for “Эффективное удаление большого каталога, содержащего тысячи файлов”

    Использование rsync удивительно быстро и просто.

     mkdir empty_dir rsync -a --delete empty_dir/ yourdirectory/ 

    @ Ответ sarath сказал еще один быстрый выбор: Perl! Его тесты быстрее, чем rsync -a --delete .

     cd yourdirectory perl -e 'for(<*>){((stat)[9]<(unlink))}' 

    Источники:

    1. https://stackoverflow.com/questions/1795370/unix-fast-remove-directory-for-cleaning-up-daily-builds
    2. http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux

    Кто-то из Twitter предложил использовать -delete вместо -exec rm -f{} \;

    Это улучшило эффективность команды, но по-прежнему использует рекурсию, чтобы пройти через все.

    Что-то вроде: find /path/to/folder -name "filenamestart*" -type f -print0 | xargs -0rn 20 rm -f find /path/to/folder -name "filenamestart*" -type f -print0 | xargs -0rn 20 rm -f

    Вы можете ограничить количество удаляемых файлов сразу, изменив аргумент параметра -n . Имена файлов с пробелами также включены.

    Расширяясь по одному из комментариев, я не думаю, что вы делаете то, что думаете, что делаете.

    Сначала я создал огромное количество файлов, чтобы имитировать вашу ситуацию:

     $ mkdir foo $ cd foo/ $ for X in $(seq 1 1000);do touch {1..1000}_$X; done 

    Затем я попробовал то, что ожидал, чтобы потерпеть неудачу, и как это звучит, как будто вы делаете в вопросе:

     $ rm -r foo/* bash: /bin/rm: Argument list too long 

    Но это работает:

     $ rm -r foo/ $ ls foo ls: cannot access foo: No such file or directory 

    Умный трюк:

     rsync -a --delete empty/ your_folder/ 

    Это супер-процессор интенсивный, но действительно очень быстро. См. https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html.

    У меня была возможность проверить -delete по сравнению с -exec rm \{\} \; и для меня -delete был ответом на эту проблему.

    Использование -delete файлы в папке из 400 000 файлов по меньшей мере в 1000 раз быстрее, чем rm .

    «Как удалить большое количество файлов в Linux» говорит, что это примерно на три раза быстрее, но в моем тесте разница была гораздо более драматичной.

    Существует несколько методов, которые можно использовать для удаления большого количества файлов в Linux. Вы можете использовать опцию find with delete, которая быстрее, чем опция exec. Затем вы можете использовать perl unlink, а затем rsync. Как удалить большое количество файлов в Linux

    Удаление каталогов REALLY LARGE требует другого подхода, так как я узнал на этом сайте – вам нужно будет использовать ionice.It гарантирует (с -c3), что удаление будет выполняться только тогда, когда у системы есть время ввода-вывода. Нагрузка на систему не повышается до максимума, и все остается отзывчивым (хотя время моего процессора для поиска было довольно высоким примерно на 50%).

     find <dir> -type f -exec ionice -c3 rm {} \; 

    О опции -delete выше: я использую ее для удаления большого количества файлов (1M + est) в папке temp, которую я создал, и непреднамеренно забыл очистить каждую ночь. Я случайно заполнил свой диск / раздел, и ничто не могло их удалить, но find . команда. Это медленно, сначала я использовал:

     find . -ls -exec rm {} \; 

    Но это заняло Чрезвычайное количество времени. Он начался примерно через 15 минут, чтобы удалить некоторые файлы, но я предполагаю, что он удалял менее 10 или около того в секунду после того, как он наконец начал. Итак, я попробовал:

     find . -delete 

    вместо этого, и я разрешаю этому запустить прямо сейчас. Похоже, что он работает быстрее, хотя на ЦПУ EXTREMELY накладывается так, что другой командой не было. Он работает как час, и я думаю, что снова получаю пространство на своем диске, и раздел постепенно «похудит», но он все еще занимает очень много времени. Я серьезно сомневаюсь, что он работает в 1000 раз быстрее, чем другой. Как и во всем, я просто хотел указать на компромисс в пространстве и времени. Если у вас есть пропускная способность центрального процессора (мы делаем), тогда запустите последнюю. У меня работает мой процессор (отчеты о uptime работе):

     10:59:17 up 539 days, 21:21, 3 users, load average: 22.98, 24.10, 22.87 

    И я видел, что среднее значение нагрузки превышает 30,00, что плохо для занятой системы, но для наших, которые обычно легко загружаются, все в порядке на пару часов. Я проверил большинство вещей в системе, и они все еще реагируют, и теперь у нас все в порядке.

     ls -1 | xargs rm -rf 

    должен работать внутри основной папки

    Для подсказки Изкаты выше:

    Но это работает:

     $ rm -r foo/ $ ls foo ls: cannot access foo: No such file or directory 

    Это почти сработало – или сработало бы – но у меня возникли проблемы с разрешением; файлы были на сервере, но все же я не понимаю, откуда эта проблема разрешений. В любом случае, терминал запрашивал подтверждение для каждого файла. Количество файлов было около 20 000, так что это был не вариант. После «-r» я добавил параметр «-f», поэтому вся команда была « rm -r -f имя_папки / ». Тогда это, казалось, сработало. Я новичок в терминале, но, думаю, все в порядке, не так ли? Благодаря!

    В зависимости от того, насколько хорошо вам нужно избавиться от этих файлов, я бы предложил использовать shred .

     $ shred -zuv folder 

    если вы хотите очистить каталог, но вы не можете удалить его и воссоздать, я предлагаю переместить его и мгновенно воссоздать.

     mv folder folder_del mkdir folder rm -rf folder_del 

    это быстрее, верьте или нет, так как нужно изменить только один индекс. Помните: вы не можете распараллелить этот вкус на многоядерном компьютере. Это сводится к доступу к диску, который ограничен RAID или что у вас есть.

    Рассмотрите возможность использования тома Btrfs и просто удалите весь том для такого каталога с большим количеством файлов.

    В качестве альтернативы вы можете создать файл изображения FS, затем размонтировать и удалить его файл, чтобы удалить все сразу очень быстро.

    Предполагая, что GNU- parallel установлена, я использовал это:

    parallel rm -rf dir/{} ::: `ls -f dir/`

    и это было достаточно быстро.

    Linux и Unix - лучшая ОС в мире.