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

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

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

171
05.11.2016, 19:23
17 ответов
ls -1 | xargs rm -rf 

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

0
27.01.2020, 19:28
  • 1
    ls не будет работать из-за суммы файлов в папке. Поэтому я должен был использовать find, спасибо все же. –  Toby 26.04.2012, 11:19
  • 2
    @Toby: Попробовать ls -f, который отключает сортировку. Сортировка требует, чтобы весь каталог был загружен в память, которая будет отсортирована. Неотсортированный ls должен смочь передать его вывод потоком. –  camh 26.04.2012, 13:59
  • 3
    локали, не работает над именами файлов, которые содержат новые строки. –  maxschlepzig 05.01.2014, 09:53
  • 4
    @camh это правда. Но удаление файлов в отсортированном порядке быстрее, чем в неотсортированном (из-за перевычисления B-дерева каталога после каждого удаления). См. этот ответ для примера serverfault.com/a/328305/105902 –  Marki555 29.06.2015, 15:50
  • 5
    @maxschlepzig для таких файлов можно использовать find . -print0 | xargs -0 rm, который будет использовать ПУСТОЙ символ в качестве разделителя имени файла. –  Marki555 29.06.2015, 15:51

Подробно останавливаясь на одном из комментариев, я не думаю, что Вы делаете то, что Вы думаете, что делаете.

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

$ 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
12
27.01.2020, 19:28
  • 1
    Это - единственное решение, которое работало: Выполненный rm -Rf bigdirectory несколько раз. У меня был каталог с тысячами миллионов подкаталогов и файлов. Я не мог даже работать ls или find или rsync в том каталоге, потому что это исчерпало память. Команда rm -Rf выход много раз (из памяти) только удаление части миллиардов файлов. Но после многих повторений это наконец сделало задание. Кажется, единственное решение, если исчерпывание памяти является проблемой. –  erik 09.04.2014, 16:01

Что относительно чего-то как: find /path/to/folder -name "filenamestart*" -type f -print0 | xargs -0rn 20 rm -f

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

19
27.01.2020, 19:28
  • 1
    Вам, вероятно, не нужно -n 20 бит, с тех пор xargs должен ограничить себя приемлемыми размерами списка аргументов так или иначе. –  Useless 26.04.2012, 16:41
  • 2
    Да, Вы правы. Вот примечание от man xargs : (...) max-chars characters per command line (...). The largest allowed value is system-dependent, and is calculated as the argument length limit for exec. Так -n опция для таких случаев, где xargs не может определить размер буфера CLI или если выполняемая команда имеет некоторые пределы. –  digital_infinity 26.04.2012, 16:50

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

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

39
27.01.2020, 19:28
  • 1
    Это нестандартно. GNU find иметь -delete, и другой find возможно. –  enzotib 26.04.2012, 12:11
  • 2
    -delete должен всегда предпочитаться -exec rm когда доступно, для соображений безопасности и эффективности. –  jw013 26.04.2012, 14:37
  • 3
    GNU является фактическим стандартом. –  RonJohn 03.03.2018, 19:38

Используя 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
225
27.01.2020, 19:28
  • 1
    Спасибо, очень полезное. Я использую rsync все время, я понятия не имел, что Вы могли использовать его для удаления как это. Значительно более быстрый, чем комната-rf –  John Powell 21.08.2014, 22:41
  • 2
    rsync может быть быстрее, чем плоскость rm, потому что это гарантирует удаление в правильном порядке, таким образом, меньше btress перерасчета будет необходимо. Посмотрите этот serverfault.com/a/328305/105902 –  Marki555 29.06.2015, 15:45
  • 3
    Кто-либо может изменить выражение жемчуга для рекурсивного удаления всех каталогов и файлов в directory_to_be_deleted? –  Abhinav 06.10.2015, 18:43
  • 4
    Примечания: добавить -P опция к rsync еще для некоторого дисплея, также, быть осторожными относительно синтаксиса, запаздывающие наклонные черты обязательны. Наконец, можно запустить команду rsync в первый раз с -n опция сначала для запуска пробного прогона. –  Drasill 23.10.2015, 18:39
  • 5
    -a равняется -rlptgoD, но для удаления только -rd необходимо –  Koen. 19.03.2016, 16:36

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

$ shred -zuv folder

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

mv folder folder_del
mkdir folder
rm -rf folder_del

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

0
27.01.2020, 19:28

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

Но это действительно работает:

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

Это почти работало - или будет работать - но у меня были некоторые проблемы в разрешении; файлы были на сервере, но тем не менее я не понимаю, куда эта проблема разрешения прибыла из. Так или иначе, Терминал, который попросили подтверждения на каждом файле. Сумма файлов была приблизительно 20 000, таким образом, это не было опцией. После "-r" я добавил опцию "-f", таким образом, целая команда была "комнатой-r-f foldername /". Затем это, казалось, хорошо работало. Я - новичок с Терминалом, но я предполагаю, что это было хорошо, правильно?Спасибо!

0
27.01.2020, 19:28

Для каталогов Deleting REALLY LARGE нужен другой подход, как я узнал из этого сайта - необходимо будет использовать, ионизируются. Это удостоверяется (с-c3), который удаляет, будет только выполнен, когда система имеет IO-time для него. Вы системная загрузка не повысится до высокого и все остается быстро реагирующим (хотя мое процессорное время для находки было довольно высоко приблизительно в 50%).

find <dir> -type f -exec ionice -c3 rm {} \;
1
27.01.2020, 19:28
  • 1
    + вместо \; сделал бы это быстрее, поскольку это передает больше аргументов комнате сразу, меньше разветвляющегося –  xenoterracide 03.01.2014, 19:50

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

3
27.01.2020, 19:28

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

Используя -delete удаленный файлы в папке 400 000 файлов по крайней мере в 1,000 раз быстрее, чем rm.

Статья 'How to delete large number of files in linux' предполагает, что это приблизительно в три раза быстрее, но в моем тесте различие было намного более поразительным.

8
27.01.2020, 19:28
  • 1
    Используя find -exec выполняется rm команда для каждого файла отдельно, вот почему это настолько медленно. –  Marki555 27.06.2015, 00:43

Умный прием:

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

14
27.01.2020, 19:28
  • 1
    ответа, Это не настолько быстро, потому что это читает содержание каталога неэффективно. См. этот ответ для 10x, более быстрое решение и объяснение serverfault.com/a/328305/105902 –  Marki555 29.06.2015, 15:46
  • 2
    @Marki555: в Редактировании вопроса об этом сообщают 60 секунд для rsync -a --delete по сравнению с 43 для lsdent. Отношение 10x было для time ls -1 | wc -l по сравнению с time ./dentls bigfolder >out.txt (который является частично справедливым сравнением из-за > file по сравнению с wc -l). –  Hastur 21.01.2016, 11:30

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

find . -ls -exec rm {} \;

Но это занимало ЭКСТРЕМАЛЬНОЕ количество времени. Это начало приблизительно после 15 минут удалять некоторые файлы, но мое предположение - то, что это удаляло меньше чем приблизительно 10 в секунду после того, как это наконец запустилось. Так, я попробовал:

find . -delete

вместо этого, и я позволяю ему работать прямо сейчас. Это, кажется, работает быстрее, хотя это является ЧРЕЗВЫЧАЙНО налоговым на ЦП, которым не была другая команда. Это выполняло для подобного час теперь, и я думаю, что возвращаю пространство на своем диске и разделе, постепенно "сокращающем", но все еще требуется очень долгое время. Я серьезно сомневаюсь, что это работает в 1,000 раз быстрее, чем другой. Как во всех вещах, я просто хотел указать на компромисс в пространстве по сравнению со временем. Если у Вас есть пропускная способность ЦП для экономии (мы делаем), затем выполняет последнего. Это имеет мое выполнение ЦП (uptime отчеты):

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

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

5
27.01.2020, 19:28
  • 1
    , если Вы собираетесь использовать exec Вы почти наверняка хотите не, используют -ls и сделайте find . -type f -exec rm '{}' + + быстрее, потому что это даст столько аргументов комнате, сколько это может обработать сразу. использование –  xenoterracide 03.01.2014, 19:48
  • 2
    я думаю, что необходимо идти вперед и отредактировать это в его собственный ответ …, это действительно слишком длинно для комментария. Кроме того, это кажется, что Ваша файловая система имеет довольно дорогой, удаляет, любопытный, какой это? Можно выполнить это find … -delete через nice или ionice, это может помочь. Так мог бы изменение некоторых монтировать опции к less-crash-safe настройкам. (И, конечно, в зависимости от того, что еще находится в файловой системе, самый быстрый способ удалить все часто mkfs.) –  derobert 04.01.2014, 09:24
  • 3
    Средним числом Загрузки является не всегда ЦП, это - просто мера количества заблокированных процессов со временем. Процессы могут заблокировать на диске ввод-вывод, который вероятен, что происходит здесь. –  Score_Under 14.07.2014, 15:47
  • 4
    Также отмечают, что среднее число загрузки не составляет количество логических центральных процессоров. Так loadavg 1 поскольку одножильная машина совпадает с loadavg 64 в системе с 64 ядрами - значение каждого ЦП составляет занятые 100% времени. –  Marki555 29.06.2015, 15:49

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

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

5
20.08.2021, 13:26

Если вы просто хотите избавиться от большого количества файлов как можно скорее, ls -f1 /path/to/folder/with/many/files/ | xargs rmможет работать нормально, но лучше не запускать его в производственных системах, потому что в вашей системе могут возникнуть проблемы с вводом-выводом, а приложения могут зависнуть во время операции удаления..

Этот сценарий прекрасно работает со многими файлами и не должен влиять на загрузку системы.

#!/bin/bash

# Path to folder with many files
FOLDER="/path/to/folder/with/many/files"

# Temporary file to store file names
FILE_FILENAMES="/tmp/filenames"

if [ -z "$FOLDER" ]; then
    echo "Prevented you from deleting everything! Correct your FOLDER variable!"
    exit 1
fi

while true; do
    FILES=$(ls -f1 $FOLDER | wc -l)
    if [ "$FILES" -gt 10000 ]; then
        printf "[%s] %s files found. going on with removing\n" "$(date)" "$FILES"
        # Create new list of files
        ls -f1 $FOLDER | head -n 5002 | tail -n 5000 > "$FILE_FILENAMES"

        if [ -s $FILE_FILENAMES ]; then
            while read FILE; do
                rm "$FOLDER/$FILE"
                sleep 0.005
            done < "$FILE_FILENAMES"
        fi
    else
        printf "[%s] script has finished, almost all files have been deleted" "$(date)"
        break
    fi
    sleep 5
done
0
20.08.2021, 13:26

Используйте rm -rf directoryвместо rm -rf *.

Первоначально мы выполняли rm -rf *в каталоге, чтобы очистить содержимое, и думали, что это будет максимально быстро. Но затем один из наших старших инженеров предложил избегать использования звездочек(*)и вместо этого передавать родительский каталог, например rm -rf directory.

После долгих дебатов о том, что это не имеет значения, мы решили протестировать его вместе с третьим методом использования find. Вот результаты:

time rm -rf *                   2m17.32s
time rm -rf directory           0m15.60s
time find directory -delete     0m16.97s

rm -rf directoryпримерно в 9 РАЗ БЫСТРЕЕ, чем rm -rf *!

Само собой разумеется, мы купили этому инженеру пива!

Итак, теперь мы используем rm -rf directory; mkdir directoryдля удаления каталога и повторного -его создания.

10
20.08.2021, 13:26

Скрипты Python не следует избегать как нечистые:

#!/usr/bin/python3

import shutil
path_for_deletion = input( 'path of dir for deletion> ' ) 
print( 'about to remove ' + path_for_deletion + '...' )
shutil.rmtree( path_for_deletion, ignore_errors=True )
print( '... done' )

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

Ошибки NB могут быть обработаны, чтобы хотя бы распечатать их... но может быть проще запустить trash myDirectoryForDeletionили rm -rfv myDirectoryForDeletionпосле этого.

1
20.08.2021, 13:26

Используйте ls -f | xargs -n 5000 rm, регулируя -nдля размера партии в соответствии с вашей системой (kudos to @digital _infinity for -nнаконечник ).

Кроме того, вы можете отфильтровать список с помощью встроенной команды grep, например. ls -f | grep '^156' | xargs -n 5000 rm.

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

1
20.08.2021, 13:26

Теги

Похожие вопросы