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


140

Я намагаюся опрацювати команду, яка видаляє файли 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

Що я роблю неправильно?

Відповіді:


274

Ви на самому справі обжигающе 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

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

Вибере файли /usr/www/bar/htdocsстарше 15 днів та видалить їх.


Я вважаю за краще вашу відповідь, ніж прийняту через "пробіл в імені". Це краще обробляється командою "-exec", ніж pipe. Дякую.
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 {} \;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.