Как я могу удалить все файлы из каталога, когда он сообщает «Список аргументов слишком длинный»

11

У меня есть каталог с парой сотен тысяч файлов в нем.

Я хочу удалить все файлы, но rm * -f сообщает: "список аргументов слишком длинный"

Каков наилучший способ очистить этот каталог?

казарка
источник
Связанные, полудубликаты
Денилсон Са Майя

Ответы:

11

Если вы не можете удалить каталог, вы всегда можете использовать поиск.

find . -maxdepth 1 -type f -exec rm -f {} \;

Это удалит все файлы в текущем каталоге, и только текущий каталог (не подкаталоги).

skraggy
источник
почти идеально (см. мой пост тоже)
asdmin
2
В Linux вы можете сделать это еще быстрее, используя «+» вместо «\;». Это заставит его удалять больше файлов за «rm» за один раз.
Томас
5
Еще быстрее: find dir/to/delete -delete(не порождает rmпроцесс на файл для удаления).
Мортен Зибур
Мортен: он никогда не упоминал о желании удалить сам каталог, он сказал, что онкиные файлы. find dir/to/delete -type f -delete
Ричо
21
находить . -maxdepth 1 -тип f -exec rm -f {} \;

это просто занимает слишком много времени (один исполняемый файл rm на файл).

этот гораздо эффективнее:

находить . -maxdepth 1 -тип f -print0 | xargs -r0 rm -f

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

asdmin
источник
5
Рад видеть, что кто-то знает, как работает find ... Также рассмотрим с новым gnu find действие -delete или команду -exec {} +, которая действует как xargs. Смотрите раздел Действия в «man find».
Кайл Брандт
Я не знал о -exec cmd {} +. Это выглядит довольно полезным. Чуть более общий, чем -delete :)
Дэвид Пашли
-delete может быть хорошо, но я лично предпочитаю команды, которые могут быть использованы на различных машинах. Системы Solaris, с которыми я работаю, старше, поэтому -delete не будет работать на них
asdmin
2
Добавление ioniceнепосредственно перед этим rmявляется хорошей идеей, если компьютер используется другими людьми одновременно.
Хьюберт Карио
6

Оба они обойдут проблему. Существует анализ соответствующей работы каждого метода над здесь .

find . -name WHATEVER -exec rm -rf {} \;

или

ls WHATEVER | xargs rm -rf

Проблема связана с расширением bash расширением "*" с помощью элемента everysingle в каталоге. Оба эти решения работают через каждый файл по очереди вместо этого.

Coops
источник
2
Решение для поиска медленнее со многими файлами, потому что оно вызывает команду rm для каждого отдельного файла. Решение xargs быстрее, но оно работает только тогда, когда имена файлов не содержат пробелов (в противном случае вам понадобится GNU find и find . -print0 | xargs -0 rm).
Robcast
"find. -name WHATEVER -print0 | xargs -0 rm -rf" будет более эффективным. find будет форкать rm для каждого файла, где xargs уменьшит его до минимума. Вам нужны -print0 и -0, чтобы справляться с файлами с пробелами в них. Возможно, вы также захотите использовать -depth при поиске, поэтому он выполняет поиск в глубину.
Дэвид Пашли
Команда ls не будет работать, поскольку она также возвращает «список аргументов слишком длинный»
Brent,
2
Вы делаете " ls *", и " *" расширяется до списка аргументов, который ваша оболочка жалуется на слишком длинный ls .Вместо этого используйте " " (или поднимитесь на один уровень вверх и сделайте " ls [dirname]").
Джеймс Снерингер
вторая командная строка (ls WHATEVER | xargs rm -rf) не будет работать по той же причине, что и вопрос не работал: WHATEVER будет заменен на shell с превышением длины
asdmin
3

Я смог сделать это, сделав резервную копию одного уровня:

cd ..

И работает:

rm directory name -rf

А затем пересоздать каталог.

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

Все эти вызовы find очень хороши, но я редко помню, какая именно номенклатура нужна, когда я спешу: вместо этого я использую ls. Как кто-то упоминает, лс. будет работать, но я предпочитаю ls -1, как в:

лс -1 | xargs -n 100 rm -rf

Значение -n xxx довольно безопасно для игры, так как превышение максимального значения будет либо автоматически исправлено (если превышен размер-максимум; см. -S), либо если превышено значение args-max для приложения, обычно оно будет довольно очевидно.

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

Этот ответ предполагает, что вы используете основные утилиты Gnu для своих ls, xargs и т. Д.

rixtertech
источник
Будет ли это работать с каталогом, который слишком велик для работы "ls"? (та же ошибка - список аргументов слишком длинный)
Brent
Да, Брент: просто не используйте спецификацию файлов при вызове ls. Используйте только -1 (тире один), как показано выше. И, как объяснено выше, используйте grep после ls, если вам нужно спарить список файлов. Если вы получаете «слишком длинную» ошибку после того, как убедитесь, что не используете подстановочные знаки с ls, возможно, xargs жалуется. Используйте «xargs -n 5» вместо «xargs -n 100», и вы определенно должны быть в безопасности, если будете немного медленнее.
rixtertech
1

Вы можете использовать -exec +опцию, чтобы найти, кто попытается запустить rm как можно меньше раз, что может быть быстрее.

find . -type f -exec rm '{}' +
Рори
источник
0

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

Он работает, выпуская работу небольшими партиями (по умолчанию 100 файлов) и немного ожидая завершения других заданий.

Отлично сработало для удаления более полумиллиона файлов из одного каталога на ext3. Процент отпечатков сделан в виде небольшого бонуса

noOfFiles=`ls -U | wc -l`
n=0
while (ls -U | tail -n 100 | xargs rm -f); do 
   n=$((n+100));
   sync;
   echo -en "$((n*100/noOfFiles))%, ($n of $noOfFiles)\r";
   sleep 5;
done
Хьюберт Карио
источник
0

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

Это помогло 220 000+ файлам в папке сессий ....

Преимущество: мгновенно начинает удалять файлы

CD путь / в / папку
ls -f | xargs rm -f -v

Нажмите на снимок экрана с удаляемыми файлами - (удалили все файлы за ~ 15 минут)

-f (после ls) удерживает от предварительной сортировки

-v (после rm) отображает каждый файл как удаляемый

-f (после rm) принудительно завершает работу без запросов на файлы, защищенные от записи

Совет: сначала переименуйте папку (ex session to session_old), чтобы предотвратить добавление дополнительных автоматически сгенерированных файлов, когда вы пытаетесь удалить файлы. Вы можете переделать исходный каталог вручную, если он не будет автоматически, как в моем случае

kilcode
источник
Что нового в вашем ответе, чего не было в предыдущих?
user2233709