Linux удалить файлы рекурсивно по маске

Удаление всех файлов определённого типа в каталоге

Есть каталог rare, в нём — куча подкаталогов и файлов. Нужно удалить все .m3u файлы. Делаю:

однако эта команда оставляет .m3u файлы, если в путях есть пробелы. Как заставить её обрабатывать пробелы?

Добавить двойные кавычки

Отличный совет, чувак. Я сейчас удалил половину каталога с музыкой.

Тогда экранированные двойные кавычки.

«Чуваком» будешь отца своего звать, а я тебе ответил на вопрос касательно классического метода, что решает эту задачу.
Не зря я написал именно так, как написал.

Ууу, кто-то только что спалил виртуала

Как такое могло получиться? Вы же не скопипастили «find -delete»?

/Music -type f -name «.txt» -delete в моем случае просто удалило все .txt файлы. С чего у вас удалилась музыка, если вы удаляете .m3u только?

Update:
Не нужно никаких костылей вроде xargs, find умеет удалять файлы с параметром -delete. Но для начала без него, проверьте, чтобы find искал все необходимые файлы, а потом уже дописывайте -delete, чтобы их удалить.

Источник

eye_ru

Программер-наблюдатель

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

В Linux чуток сложнее.
Есть в Linux команда rm, но она дальше текущей директории не идет, зато прекрасно понимает полный путь к файлу, чем мы и воспользуемся.
Получить список всех файлов в текущей директории и поддиректориях по маске позволяет команда find -name «smth.*», ее вывод то нам и нужен. Осталось его перенаправить на вход команды rm. Это можно сделать 5ю способами:
xargs — формирует команду rm с аргументами считанными из стандартного ввода на которой мы подадим вывод команды find. нюансы использования описаны тут
1. find /path/to/dir -type f -name ‘smth*’ -print0 | xargs -0 rm;
exec — перенапаравляем вывод команды find на вход команды rm
2. find -name ‘smth.*’ -exec rm <> \;
UPD.
find — самый рульный способ
3. find -name ‘smth.*’ -delete;
UPD.
Способы подсказанные камрадом goodvin
4. find . -type f -name ‘smth*’ -delete
5. find . -type f -name ‘smth’ -exec rm -f — «<>» \;

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

Жестоко

Re: Жестоко

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

См. -delete в `man find`.

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

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

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

/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:

Читайте также:  Общие права доступа windows

/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
по количеству кавычек в котором можно еще и определить степень знания особенностей использования шелла 🙂

Спасибо!

Re: Спасибо!

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

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

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

xargs xargs xargs

Спасибо за пост, узнал про xargs. Все ж намного проще:

find . -name .svn|xargs rm -rf

(удаление папки .svn во всех подпапках проекта)

Источник

#!/bin/sh

Линуксоид на велосипеде с моторчиком

Рекурсивные операции с файлами в Linux

Иногда возникает путаница между опциями -r и -R, каждая из которых в разных программах может означать рекурсивную обработку файлов в найденных каталогах. А может означать нечто совершенно противоположное или работать не так, как этого ожидал пользователь. Попробуем разобраться, в каких случаях что используется.

Эпиграф

— Это новый «Гарри Поттер». Я заказал версии для детей и взрослых, чтобы проверить, что в тексте нет различий.
Морис Мосс, The IT Crowd.

chmod

Ключ -r у chmod интерпретируется как «запретить всем чтение файла», а 755 в данном случае рассматривается как название файла, у которого изменяются права. Поскольку в подавляющем большинстве случаев файла с таким названием в текущей директории отсутствует, то команда возвращает ошибку.

chown, chattr, chgrp

У вышеперечисленных команд опция -r просто отсутствует. Для рекурсивной обработки директорий необходимо использовать опцию -R. Очевидно, так сделано из солидарности с «братской» командой chmod

Несмотря на то, что в странице документации cp из GNU coreutils сказано, что опции -r и -R равнозначны и означают рекурсивную обработку встречающихся директорий, опция -r, в отличие от -R, не соответствует стандарту POSIX и ее указание может повлечь за собой неожиданные последствия в случае, если очередной копируемый объект является чем-то отличным от обычного файла или директории (например, символической ссылкой, fifo или сокетом). В таких случаях некоторые реализации cp просто копируют содержимое ссылки/fifo, тогда как при -R такие объекты пересоздаются заново. Раньше такое поведение было присуще GNU cp, о чем до сих пор имеется свидетельство в русском man cp. Что касается более правильных (чем Linux) систем, то, например, в BSD-версии cp опция -r работает в «режиме совместимости», т.е. не создает символическую ссылку заново, а копирует содержимое в файл с тем же именем.

Читайте также:  Монтировать iso astra linux

Ключ -r команды ls означает «обратный порядок сортировки»
Правильно:

rm, grep

Зато в следующих случаях употребление -r/-R равнозначно:

Что касается grep, то, во-первых, обе опции не соответствуют POSIX (но, похоже, присутствуют во всех реализациях) Во-вторых, иногда возникает путаница между опциями -i (игнорировать регистр) и -I (пропускать двоичные файлы). Но это уже тема для другого разговора 🙂

Прочие команды

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

команда -r -R
chacl рекурсия удаление ACL только с файлов
setfacl не поддерживается рекурсия
cvs номер ревизии рекурсия
diff рекурсия не поддерживается
gzip/gunzip рекурсия не поддерживается
zip рекурсия рекурсия, начиная с текущей директории (см. man zip, там есть существенная разница в обработке -r и -R)
rsync рекурсия использование относительных путей
wget рекурсия указывает список отвергаемых шаблонов

Заключение

Как видно, в большинстве случаев для указания рекурсии используется опция -r в нижнем регистре, в противовес стандартным утилитам, для которых характерно все же -R. Поэтому совет один: в случае сомнения смотрите в man, там все написано 🙂

Постскриптум

По абзацу про cp видно, что русская документация в некоторых дистрибутивах (не будем показывать пальцем на Debian и Ubuntu) не соответствует реальному положению дел. В частности, несмотря на то, что в jaunty используется GNU coreutis 6.10, русский man описывает cp версии 4.1. Желающие могут самостоятельно сравнить свою версию man 1 cp с локализованной. Другими словами, русская страница документации cp в силу своей древности вводит пользователя в заблуждение, т.е. врёт. По этой причине я рекомендую сделать apt-get remove manpages-ru.

2 комментария

    Comment by anon :

> По этой причине я рекомендую сделать apt-get remove manpages-ru

Плюсую. Помню как потерял с час времени, из за феерично переведенного мана:

If from is not NULL, and the underlying protocol provides the source address, this source address is filled in.

Если параметр from не равен NULL, а сокет не является ориентированным на соединения, то адресотправителя в сообщении не заполняется.

scp неплохо было бы упомянуть. Нигде проблем с -r/-R не испытывал, только в scp почему-то постоянно пишу -R.

Источник

удаление файлов рекурсивно по маске с датой создания не позднее чем Х дней назад

задача: удалить все файлы в категории и ее подкатегориях, которые попадают под маску, но при этом созданы не позднее чем 3 дня назад (т.е. оставим все самые свежие — за последние три дня).

Читайте также:  Общие папки windows закрыть

удаление просто по маске: find PATH -name «*.FILE_EXT» -exec rm <> \;

а как удалить с учетом требования по дате?

atime, mtime насчет «созданных» — не знаю.

find -ctime +DAYS PATH -name «*.FILE_EXT» -exec rm <> \;

DAYS — кол-во дней PATh — путь к корневой директории *.FILE_EXT — маска для файла

удалит все файлы с датой создания старше 3-х дней по заданной маске

Это делается проще: «-delete». Если ты этого не знал, то ман не прочитал, поэтому в первую очередь советую его сначала таки прочитать, а потом бежать на лор. Конкретно понадобятся опции -*time, -newer, -newer*.

удалит все файлы с датой создания старше 3-х дней

Всё-таки ман не прочитал. А там белым по чёрному написано:

-ctime n File’s status was last changed n*24 hours ago.

Это не дата создания.

-delete будет работать быстрее? если да, насколько?

я в курсе, в данном случае нужно было найти файлы именно созданные от нужной даты. в случае проверки на изменения -mtime

А просто взять и проверить лень? В случае использования «-delete» find сам сразу делает unlink(), а в случае «-exec rm» для каждого файла будет вызываться fork(), exec(), создастся новый процесс rm, который получит имя файла из командой строки, распарсит параметры и в конце концов сделает unlink. Конечно, первое быстрее, чем второе.

BTW, ещё можно так: «-exec rm ‘<>‘ +», тогда в командную строку rm передадутся сразу несколько путей и лишних процессов будет меньше, чем при «-exec rm ‘<>‘ \;».

Ты же понимаешь, что это зависит от множества факторов, и на разных компьютерах разница будет разной?

в данном случае нужно было найти файлы именно созданные от нужной даты

Ну так анонимус всё правильно говорит, потому что ctime — это не дата создания. Он может меняться. Не можешь прочитать ман, так прочитай Википедию:

-ctime — время последнего изменения владельца или прав доступа к файлу.

В тред врывается zsh, и выносит find

man я читала.
в моем случае ни права, ни группа\пользователь не меняются, и это самое близкое что я нашла к дата_создания (мне не нужна дата модификации).

если вы знаете способ сравнивать именно _дату_создания_, напишите пожалуйста

если вы знаете способ сравнивать именно _дату_создания_, напишите пожалуйста

Например, параметр «-newerBt». В данном случае будет что-то типа:

find «$path» ! -newerBt ‘3 day ago’ -delete

Но на моей ФС (ext4) это не работает — похоже, что она вообще не сохраняет дату создания. Если это так, то проблему в исходном виде решить не получится и придётся использовать ctime. Возможно, на других ФС будет работать и вариант с -newerBt.

на моей также не хранит, поэтому я и решила использовать ctime, как наиболее близкую к дате создания.

дата_создания (мне не нужна дата модификации)

Часто модификация приводит к тому, что исходный файл удаляется, вместо него остается измененная копия (inode соотвественно меняется).

vcs развернуть и смотреть дату создания его средствами не судьба?

Источник

Оцените статью