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

Я пытаюсь разработать команду, которая удаляет файлы 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

Что я делаю неправильно?


person jerrygarciuh    schedule 25.06.2012    source источник


Ответы (5)


Фактически вы подключаете вывод rm ко входу 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.

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

person Lev Levitsky    schedule 25.06.2012
comment
Спасибо. Я прочитал справочную страницу и попробовал этот флаг. Я прохожу полный путь, но возвращаюсь к / usr / www2 / bar / htdocs / foo / rsync / httpdocs / db_backups /: относительный путь потенциально небезопасен. Есть идеи, почему? - person jerrygarciuh; 25.06.2012
comment
@jerrygarciuh загляните сюда. - person Lev Levitsky; 25.06.2012
comment
благодаря. Я не уверен, что хорошо следил за сообщением, но когда я эмулировал их решение и поставил -delete в конце команды, он удалил все файлы sql независимо от времени модификации ... но у него не было предупреждения, поэтому я думаю это прогресс ... - person jerrygarciuh; 25.06.2012
comment
@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. Я не уверен, какое это имеет значение, учитывая другие варианты, которые вы использовали, но вы пробовали это? - person Lev Levitsky; 25.06.2012
comment
Нет, я этого не сделал, но ничего не было потеряно. Эти файлы синхронизируются с другим сервером, где они также хранятся. - person jerrygarciuh; 25.06.2012
comment
@jerrygarciuh, так ты понял это? была '-depth' причина? - person Lev Levitsky; 26.06.2012
comment
Привет, Лев, я на самом деле не знаю, потому что наш системный администратор взял работу и решил ее другим способом. Вот и все, что нужно для обучения на практике! - person jerrygarciuh; 26.06.2012
comment
@sarat Вторая и третья команды обрабатывают это правильно. Во второй команде для разделения аргументов используется символ \\ 0 вместо пробела. В третьем случае find обрабатывает его изнутри. - person Lev Levitsky; 16.07.2015

find /usr/www/bar/htdocs -mtime +15 -exec rm {} \;

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

person Suresh    schedule 30.08.2013
comment
Я предпочитаю ваш ответ принятому из-за пробела в имени. Лучше справиться с командой -exec, чем с конвейером. Спасибо. - person Slim Aloui; 03.05.2020

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

Например,

locate file | xargs rm
person Gautam Sreekumar    schedule 27.04.2017

Предполагая, что вы не находитесь в каталоге, содержащем файлы резервных копий * .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 {} \;
person Nick Little    schedule 06.06.2017

Используйте xargs для передачи аргументов, а параметр -rd '\ n' игнорирует пробелы в именах:

$ {command} | xargs -rd '\ n' rm

Включите --force, если вы хотите также удалить файлы, доступные только для чтения.

person Alberto Salvia Novella    schedule 17.05.2021