Baris perintah: perpipaan menemukan hasil ke rm

140

Saya mencoba untuk mengerjakan perintah yang menghapus file sql lebih tua dari 15 hari.

Bagian find berfungsi tetapi bukan rm.

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

Itu mengeluarkan daftar file yang ingin saya hapus tetapi tidak menghapusnya. Jalannya benar.

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

Apa yang saya lakukan salah?

jerrygarciuh
sumber

Jawaban:

274

Anda benar-benar perpipaan rm's keluaran ke input dari find. Yang Anda inginkan adalah menggunakan output findsebagai argumen untuk rm:

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

xargsadalah perintah yang "mengubah" input standarnya menjadi argumen dari program lain, atau, karena mereka lebih akurat meletakkannya di manhalaman,

membangun dan mengeksekusi baris perintah dari input standar

Perhatikan bahwa jika nama file dapat berisi karakter spasi, Anda harus memperbaikinya:

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

Tetapi sebenarnya, findmemiliki jalan pintas untuk ini: -deleteopsi:

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

Harap perhatikan peringatan berikut di 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 Perhatikan bahwa pemipaan langsung ke rmbukan merupakan opsi, karena rmtidak mengharapkan nama file pada input standar. Apa yang Anda lakukan saat ini adalah memipkannya ke belakang.

Lev Levitsky
sumber
1
Terima kasih. Saya membaca halaman manual dan mencoba bendera itu. Saya melewati jalur lengkap tetapi mendapatkan kembali "/ usr / www2 / bar / htdocs / foo / rsync / httpdocs / db_backups /: jalur relatif berpotensi tidak aman". Ada yang tahu kenapa?
jerrygarciuh
1
@jerrygarciuh lihat di sini .
Lev Levitsky
Terima kasih. Saya tidak yakin saya mengikuti posting dengan baik tetapi ketika saya meniru solusi mereka dan meletakkan -delete di akhir perintah itu menghapus semua file sql terlepas dari waktu mod ... tetapi tidak memiliki peringatan jadi saya kira itu kemajuan ...
jerrygarciuh
1
@jerrygarciuh Ouch, saya harap tidak ada yang berharga yang hilang ... manmengatakan: 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.Saya tidak yakin bagaimana itu akan berarti mengingat opsi lain yang Anda gunakan, tetapi, apakah Anda mencobanya?
Lev Levitsky
Tidak, tapi tidak ada yang hilang. File-file ini rsync-ed dari server lain di mana mereka juga disimpan.
jerrygarciuh
26
find /usr/www/bar/htdocs -mtime +15 -exec rm {} \;

Akan memilih file yang /usr/www/bar/htdocslebih lama dari 15 hari dan menghapusnya.

Suresh
sumber
Saya lebih suka jawaban Anda daripada yang diterima karena "spasi dalam nama". Lebih baik ditangani dengan perintah "-exec" daripada pipa. Terima kasih.
Slim Aloui
3

Metode lain yang lebih sederhana adalah dengan menggunakan locateperintah. Kemudian, pipa hasilnya ke xargs.

Sebagai contoh,

locate file | xargs rm
Gautam Sreekumar
sumber
2

Dengan asumsi Anda tidak berada di direktori yang berisi file cadangan * .sql:

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

Opsi -v di atas berguna karena secara verbal akan menampilkan file mana yang sedang dihapus saat dihapus.

Saya ingin daftar file yang akan dihapus terlebih dahulu untuk memastikan. Misalnya:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec ls -lrth {} \;
Nick Little
sumber