Командная строка: отправка результатов поиска в rm

144

Я пытаюсь разработать команду, которая удаляет файлы sql старше 15 дней.

Часть поиска работает, но не rm.

rm -f | find -L /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups -type f  \( -name '*.sql' \) -mtime +15

Он выдает список именно тех файлов, которые я хочу удалить, но не удаляет их. Пути правильные.

usage: rm [-f | -i] [-dIPRrvW] file ...
       unlink file
/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/20120601.backup.sql
...
/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/20120610.backup.sql

Что я делаю не так?

Jerrygarciuh
источник

Ответы:

282

Вы на самом деле обжигающе rm«s выход к входу find. Вы хотите использовать вывод в findкачестве аргументов для rm:

find -type f -name '*.sql' -mtime +15 | xargs rm

xargsэто команда, которая «преобразует» свой стандартный ввод в аргументы другой программы, или, как они точнее помещают ее на manстраницу,

создавать и выполнять командные строки из стандартного ввода

Обратите внимание, что если имена файлов могут содержать символы пробела, вы должны исправить это:

find -type f -name '*.sql' -mtime +15 -print0 | xargs -0 rm

Но на самом деле findдля этого есть ярлык: -deleteопция:

find -type f -name '*.sql' -mtime +15 -delete

Обратите внимание на следующие предупреждения man find:

  Warnings:  Don't  forget that the find command line is evaluated
  as an expression, so putting -delete first will make find try to
  delete everything below the starting points you specified.  When
  testing a find command line that you later intend  to  use  with
  -delete,  you should explicitly specify -depth in order to avoid
  later surprises.  Because -delete  implies  -depth,  you  cannot
  usefully use -prune and -delete together.

PS Обратите внимание, что прямая передача по конвейеру rmне является вариантом, потому rmчто не ожидает имен файлов на стандартном вводе. То, что вы сейчас делаете, - это перекачивание их в обратном направлении.

Лев Левицкий
источник
1
Спасибо. Я прочитал страницу руководства и попробовал этот флаг. Я прохожу полный путь, но возвращаюсь "/ usr / www2 / bar / htdocs / foo / rsync / httpdocs / db_backups /: относительный путь потенциально небезопасен". Есть идеи, почему?
jerrygarciuh
1
@jerrygarciuh, взгляни здесь .
Лев Левицкий
Спасибо. Я не уверен, что хорошо следил за сообщением, но когда я эмулировал их решение и поставил -delete в конце команды, он удалил все файлы sql независимо от времени модификации ... но у него не было предупреждения, поэтому я думаю это прогресс ...
jerrygarciuh
1
@jerrygarciuh Ой, надеюсь, ничего ценного не было потеряно ... manговорит: When testing a find command line that you later intend to use with -delete, you should explicitly specify -depth in order to avoid later surprises.Я не уверен, что это будет иметь значение, учитывая другие варианты, которые вы использовали, но вы пробовали это?
Лев Левицкий
Нет, я этого не сделал, но ничего не было потеряно. Эти файлы rsync-ed с другого сервера, где они также хранятся.
jerrygarciuh
27
find /usr/www/bar/htdocs -mtime +15 -exec rm {} \;

Выбирает файлы /usr/www/bar/htdocsстарше 15 дней и удаляет их.

Суреш
источник
Я предпочитаю ваш ответ принятому из-за «пробела в имени». С этим лучше справиться командой «-exec», чем с конвейером. Спасибо.
Slim Aloui
3

Другой более простой метод - использовать locateкоманду. Затем перенесите результат в xargs.

Например,

locate file | xargs rm
Гаутам Срикумар
источник
2

Предполагая, что вы не находитесь в каталоге, содержащем файлы резервных копий * .sql:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec rm -v {} \;

Опция -v выше удобна: она подробно выводит, какие файлы удаляются по мере их удаления.

Мне нравится перечислять файлы, которые будут удалены первыми, чтобы быть уверенным. Например:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec ls -lrth {} \;
Ник Литтл
источник