Dòng lệnh: đường ống tìm kết quả để rm


140

Tôi đang cố gắng thực hiện một lệnh xóa các tệp sql cũ hơn 15 ngày.

Phần tìm thấy đang làm việc nhưng không phải là rm.

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

Nó đưa ra một danh sách chính xác các tập tin tôi muốn xóa nhưng không xóa chúng. Các đường dẫn là chính xác.

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

Tôi đang làm gì sai?

Câu trả lời:


274

Bạn thực sự rmđầu ra của đường ống đến đầu vào của find. Những gì bạn muốn là sử dụng đầu ra của findlàm đối số để rm:

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

xargslà lệnh "chuyển đổi" đầu vào tiêu chuẩn của nó thành các đối số của một chương trình khác, hoặc, khi họ đặt nó chính xác hơn trên mantrang,

xây dựng và thực thi các dòng lệnh từ đầu vào tiêu chuẩn

Lưu ý rằng nếu tên tệp có thể chứa các ký tự khoảng trắng, bạn nên sửa cho điều đó:

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

Nhưng thực ra, findcó một lối tắt cho việc này: -deletetùy chọn:

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

Xin lưu ý các cảnh báo sau trong 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 Lưu ý rằng đường ống trực tiếp rmkhông phải là một tùy chọn, vì rmkhông mong đợi tên tệp trên đầu vào tiêu chuẩn. Những gì bạn đang làm là dẫn chúng ngược lại.


1
Cảm ơn. Tôi đọc trang người đàn ông và thử lá cờ đó. Tôi đang vượt qua một đường dẫn đầy đủ nhưng nhận lại "/ usr / www2 / bar / htdocs / foo / rsync / httpdocs / db_backups /: đường dẫn tương đối có khả năng không an toàn". Bất cứ ý tưởng tại sao?
jerrygarciuh

1
@jerrygarciuh hãy xem đây .
Lev Levitsky

cảm ơn. Tôi không chắc là tôi đã theo dõi bài viết tốt nhưng khi tôi mô phỏng giải pháp của họ và đặt -delete vào cuối lệnh, nó đã xóa tất cả các tệp sql bất kể thời gian mod ... nhưng tôi đoán là không có cảnh báo nên tôi đoán đó là sự tiến bộ ...
jerrygarciuh

1
@jerrygarciuh Ouch, tôi hy vọng không có gì quý giá bị mất ... mannói: 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.Tôi không chắc vấn đề đó sẽ như thế nào khi đưa ra các lựa chọn khác mà bạn đã sử dụng, tuy nhiên, bạn đã thử chưa?
Lev Levitsky

Không, tôi không có gì nhưng đã mất. Các tệp này được rsync-ed từ một máy chủ khác, nơi chúng cũng được lưu trữ.
jerrygarciuh

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

Sẽ chọn các tệp trong /usr/www/bar/htdocshơn 15 ngày và loại bỏ chúng.


Tôi thích câu trả lời của bạn hơn câu trả lời được chấp nhận vì "khoảng trống trong tên". Nó được xử lý tốt hơn với lệnh "-exec" so với đường ống. Cảm ơn.
Slim Aloui

3

Một phương pháp đơn giản hơn là sử dụng locatelệnh. Sau đó, ống kết quả đến xargs.

Ví dụ,

locate file | xargs rm

2

Giả sử bạn không có trong thư mục chứa các tệp sao lưu * .sql:

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

Tùy chọn -v ở trên rất tiện dụng, nó sẽ xuất ra một cách rõ ràng những tập tin nào đang bị xóa khi chúng bị xóa.

Tôi muốn liệt kê các tập tin sẽ bị xóa đầu tiên để chắc chắn. Ví dụ:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec ls -lrth {} \;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.