Linux удалить файлы во вложенных папках

Обновлено: 06.07.2024

Казалось бы, простая задачка. В Windows все просто - del /S smth.*, готово. Все файлы по маске smth.* в текущей директории и ниже будут удалены.

Может есть ещё какие нибудь способы??

Жестоко

> Может есть ещё какие нибудь способы?

См. -delete в `man find`.

В *nix все просто - rm -r smth.*, готово. Все файлы по маске smth.* в текущей директории и ниже будут удалены.

что значит не работает?

права то на удаление есть?

какую ошибку пишет?

/test$ ls -R
.:
smth.123 smth.1231 smth.12311 -smth sd.1231 smth sd.1231 test

./test:
smth.123 smth.1231 smth.12311 -smth ss.111 smth ss.111
rr@pc:

/test$ rm -rvf *smth*
rm: invalid option -- s
Try `rm ./'-smth sd.1231'' to remove the file `-smth sd.1231'.
Try `rm --help' for more information.
rr@pc:

/test$ ls -R
.:
smth.123 smth.1231 smth.12311 -smth sd.1231 smth sd.1231 test

./test:
smth.123 smth.1231 smth.12311 -smth ss.111 smth ss.111
rr@pc:

/test$ ls -R
.:
gentest.sh smth.123 smth.1231 smth.12311 -smth sd.1231 smth sd.1231 test

./test:
smth.123 smth.1231 smth.12311 -smth ss.111 smth ss.111
rr@pc:

/test$ rm -- *smth*
rr@pc:

./test:
smth.123 smth.1231 smth.12311 -smth ss.111 smth ss.111
rr@pc:

У нас в конторе один из любимейших вопросов на собеседовании: как удалить сто тыщ мильонов файлов с заранее неизвестными названиями в одной директории?
Ответы типа "rm -f /path/to/dir/*" не подходят, поскольку звездочка преобразовывается в список файлов, удовлетворяющих wildmat'у (в данном случае -- все файлы), а у шелла есть ограничение на размер командной строки.
Тот же результат будет у "find /path/to/dir -type f| xargs rm", поскольку, во-первых xargs преобразует весь stdin в одну строку (try: "find /tmp |xargs echo rm"), во-вторых, в именах файлов могут содержаться пробелы, которые не эскейпятся, в-третьих, названия файлов могут начинаться на -, из-за чего rm воспримет имя файла как неизвестную опцию и упадет. Ну и ограничение на длину команды никто не отменял. Первые три проблемы обходятся так:
find /path/to/dir -type f -print0 |xargs -0 rm --
Опция -print0 какбэ говорит команде find, что в качестве разделителей нужно использовать нулевой символ вместо перевода строки, а -0 указывает xargs, что разделитель -- не пробел, а все тот же нулевой символ.

Поэтому правильным ответом считается команда
find . -type f -name 'smth*' -delete
или
find . -type f -name 'smth' -exec rm -f -- "<>" \;

Ну или простенький цикл:
for f in "`find . -type f -name 'smth*'`" ; do rm "$f"; done
по количеству кавычек в котором можно еще и определить степень знания особенностей использования шелла :)

> во-первых xargs преобразует весь stdin в одну строку
а про опцию -n забыли?

Спасибо!

Большое спасибо за понятный мануал, очень помогло.
Второй способ, кстати, не работает - пишет "missing arguments for -exec". Система Ubuntu 8.10, ядро 2.6.27

И, наконец, вот команда, которая будет выполнена для каждого файла:

-exec ln <> /var/www/obsolete \;

Здесь вы также должны дезактивировать знак ;, в противном случае командный процессор интерпретирует его как разделитель команд. Если вы забудете сделать это, find пожалуется, что для -exec отсутствует аргумент.

Имеется каталог, с большим количеством подкаталогов и уровнем вложенности который определить не представляется возможным.
Общий размер каталога около 20Гб, количество файлов более 10 млн. Точное количество файлов определить не хватило терпения (более 3 часов ждал, не долждался), а размер определил методом: вычесть из общего размера занятого на диске размер прочих каталогов, чей размер определить удалось.

Задача: удалить этот каталог со всем его содержимым за минимальный промежуток времени и с минимальным износом ЖД (все это дело на ноутбуке).

Может кто другие, более производительные методы подскажет?

перенести все остальное на другой винт, а этот форматнуть и впредь так не делать

подробнее пожалуйста, если можно?

а) +1 за идею забэкапить все кроме этого каталога, снести все нафиг, восстановить все кроме каталога

б) поставить rm -rf на ночь или выходные и не париться, ничего жесткому диску не будет

afiskon ★ ( 27.03.15 14:45:32 )
Последнее исправление: afiskon 27.03.15 14:45:44 (всего исправлений: 1)

А по inode-у удалить разве нельзя? Грохни inode каталога и все, прощай файлики. How to: Linux / UNIX Delete or Remove Files With Inode Number

ждал 3 часа, освободило не более 3 Гб

Ну подожди еще сутки. Можно подумать, ты эти три часа педали крутил чтоб оно удалялось.


И дальше по теме :)

Ну, или для Ъ — rsync

KRoN73 ★★★★★ ( 27.03.15 16:25:49 )
Последнее исправление: KRoN73 27.03.15 16:31:31 (всего исправлений: 1)

Стандартное решение: unlink верхней директории, следом umount и fsck.


unlink не работает с каталогами

Дык, я только что сидел, пытался. Оказывается, поломали, сволочи!

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



или ты имел в виду сискол?

Да пофиг. Главное — поломали же такую классную вещь.


greenman ★★★★★ ( 27.03.15 16:49:33 )
Последнее исправление: greenman 27.03.15 16:52:54 (всего исправлений: 1)


потом fsck скажет что ему вусмерть надо поработать и вернет всё в lost+found

Чушь. И да, на reiserfs нет директории lost&found!


А про износ диска ТС-у никто не ответил. Может ему нужно перемонтировать ФС или что написать в /proc, чтобы было усиленное кеширование записи?

Такое вытворял не я, а человек работавший ранее на этом рабочем месте. Сносить все это хозяйство опять же не предоставляется возможным, слишком много инфы + / & /home в одном разделе, так что.


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

А вот если задача становится многократно, я бы посоветовал посмотреть в сторону reisrefs. Мне часто приходится работать с кешами, когда несколько десятков или сотен тысяч файлов на несколько гигабайт или десятков гигабайт лежат в на 2-3 уровнях вложенности в подкаталогах. ext4 на такой структуре через какое-то время использования становится адом. Я несколько лет мучился, пока не рискнул reisrefs проверить, памятуя, что лет 10-15 назад серьёзных проблем с такими структурами (с небольшими поправками на развитие железа) у меня не было. А вправду, одна только синхронизация по rsync на таких объёмах, занимая на ext4 десяток минут, на reiserfs отрабатывает за минуту. Даже (на машинах без lvm, когда легко не переразбить диск) быстрее оказывается в плане скорости поставить reisrefs в файл-образ на ext4.

у меня есть этот список файлов внутри Linux server:

Я удаляю выбранные файлы журнала один за другим, используя команду rm -rf см. ниже:

есть ли другой способ, чтобы я мог удалить выбранные файлы сразу??

Bash поддерживает все виды подстановочных знаков и расширений.

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

больше расширить до одна команда со всеми тремя аргументами и эквивалентна набору:

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

использовать подстановочный знак ( * ) для выбора нескольких файлов.

например, следующая команда удаляет все файлы с именами, начинающимися с abc.log.2012-03- .

Я бы рекомендовал под управлением ls abc.log.2012-03-* чтобы перечислить файлы, чтобы вы могли видеть, что вы собираетесь удалить перед запуском .

для получения более подробной информации см. страницу bash man на расширение имени файла.

если вы хотите удалить все файлы, имена которых соответствуют определенной форме, по шаблону (шаблон Глоб) является наиболее простым решением. Некоторые примеры:

регулярные выражения более мощные, чем подстановочные знаки; вы можете кормить вывод grep to rm -f . Например, если некоторые имена файлов начинаются с "abc.log" и с "ABC.log" , grep можно сделать без учета регистра:

когда я это делаю, я запускаю сначала проверьте, что он выдает результат, который я хочу -- особенно если я использую rm -f :

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

это предполагает, что вы используете оболочку Bash. Некоторые другие оболочки, особенно csh и tcsh и некоторые более старые оболочки SH, могут не поддерживать $(. ) синтаксис. Вы можете использовать эквивалентный backtick синтаксис:

на $(. ) синтаксис легче читать, и если вы действительно амбициозны, он может быть вложен.

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

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

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

или, при редактировании list файл, я могу добавить rm -f в начале каждой строки, а затем:

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

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

просто используйте многострочный выбор в sublime, чтобы объединить все файлы в одну строку и добавить пробел между каждым именем файла, а затем добавить rm в начале списка. Это в основном полезно, когда в именах файлов, которые вы хотите удалить, нет шаблона.

Я не гуру linux, но я считаю, что вы хотите передать свой список выходных файлов в xargs rm -rf . Я использовал нечто подобное в прошлом с хорошими результатами. Сначала проверьте пример каталога!

EDIT - возможно, я неправильно понял, основываясь на других ответах, которые появляются. Если вы можете использовать подстановочные знаки, отлично. Я предположил, что ваш исходный список, который вы отобразили, был сгенерирован программой, чтобы дать вам ваш "выбор", поэтому я подумал, что xargs был бы путь к идти.

Если вы хотите удалить все файлы, которые относятся к каталог сразу. Например; имя каталога yor - "log", а каталог" log " включает abc.бревно.2012-03-14, abc.бревно.2012-03-15. файлы ect. Вы должны быть над каталогом журнала и

В операционной системе Linux можно выполнить большинство действий через терминал. Удаление каталога Linux - это достаточно простое действие, которое можно выполнить просто открыв файловый менеджер.

Однако в терминале это делается немного быстрее и вы получаете полный контроль над ситуацией. Например, можете выбрать только пустые папки или удалить несколько папок с одним названием. В этой статье мы рассмотрим как удалить каталог Linux через терминал.

Как удалить каталог Linux

Существует несколько команд, которые вы можете использовать для удаления каталога Linux. Рассмотрим их все более подробно. Самый очевидный вариант - это утилита rmdir. Но с помощью нее можно удалять только пустые папки:


Другая команда, которую можно применить - это rm. Она предназначена для удаления файлов Linux, но может использоваться и для папок если ей передать опцию рекурсивного удаления -r:



Такая команда уже позволяет удалить непустой каталог Linux. Но, можно по-другому, например, если вы хотите вывести информацию о файлах, которые удаляются:

rm -Rfv моя_папка

Команда -R включает рекурсивное удаление всех подпапок и файлов в них, -f - разрешает не удалять файлы без запроса, а -v показывает имена удаляемых файлов. В этих примерах я предполагаю что папка которую нужно удалить находится в текущей рабочей папке, например, домашней. Но это необязательно, вы можете указать полный путь к ней начиная от корня файловой системы:

rm -Rfv /var/www/public_html

Читайте подробнее про пути в файловой системе в статье путь к файлу Linux. Теперь вы знаете как удалить непустой каталог в консоли linux, далее усложним задачу, будем удалять папки, которые содержат определенные слова в своем имени:

find . -type d -name "моя_папка" -exec rm -rf <> \;


Подробнее про команду find смотрите в отдельной статье. Если кратко, то -type d указывает, что мы ищем только папки, а параметром -name задаем имя нужных папок. Затем с помощью параметра -exec мы выполняем команду удаления. Таким же образом можно удалить только пустые папки, например, в домашней папке:

/ -empty -type d -delete

Как видите, в find необязательно выполнять отдельную команду, утилита тоже умеет удалять. Вместо домашней папки, можно указать любой нужный вам путь:

find /var/www/public_html/ -empty -type d -delete

Перед удалением вы можете подсчитать количество пустых папок:

find /var/www/public_html/ -empty -type d | wc -l


Другой способ удалить папку linux с помощью find - использовать в дополнение утилиту xargs. Она позволяет подставить аргументы в нужное место. Например:

/ -type f -empty -print0 | xargs -0 -I <> /bin/rm "<>"

Опция -print0 выводит полный путь к найденному файлу в стандартный вывод, а затем мы передаем его команде xargs. Опция -0 указывает, что нужно считать символом завершения строки \0, а -I - что нужно использовать команду из стандартного ввода.

Если вы хотите полностью удалить папку Linux, так, чтобы ее невозможно было восстановить, то можно использовать утилиту wipe. Она не поставляется по умолчанию, но вы можете ее достаточно просто установить:

sudo apt install wipe

Теперь для удаления каталога Linux используйте такую команду:

Опция -r указывает, что нужно удалять рекурсивно все под папки, -f - включает автоматическое удаление, без запроса пользователя, а -i показывает прогресс удаления. Так вы можете удалить все файлы в папке linux без возможности их восстановления поскольку все место на диске где они были будет несколько раз затерто.

Выводы

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

Читайте также: