ls | grep | rm - Làm thế nào để định dạng lệnh này?


11

Tôi đang cố gắng xóa một loạt các tệp trong một thư mục nhất định (trên Mac OS X bằng Terminal)

ls | grep \([1-9]\) | xargs rm

nên thực hiện các mẹo, nhưng nó không. Tôi đang cố gắng xóa bất kỳ tệp nào có một chữ số trong ngoặc đơn trong tên tệp (bản sao được tải xuống từ web), nhưng cuối cùng nó lại làm một cái gì đó như thế này:

> rm: 520syllabus2010: No such file or
> directory rm: (3).pdf: No such file or
> directory

bởi vì nó không giải thích không gian chính xác. Nó sẽ xóa "520syllabus2010 (3) .pdf"

Cách thích hợp để làm điều này là gì?

Cảm ơn, Jeff


1
Tên tệp ví dụ của bạn không chứa chữ #.
Benjamin Bannier

1
@honk: Anh ấy không tìm kiếm một nghĩa đen #.
Ignacio Vazquez-Abrams

1
Do mở rộng bởi trình bao, điều này sẽ không hoạt động như mong đợi nếu cwd có tệp có tên, ví dụ: (3). Tốt nhất là trích dẫn các đối số để shell không ảnh hưởng đến chúng.
Ignacio Vazquez-Abrams

1
Bạn đang bị ảnh hưởng bởi vấn đề phân cách vi.wikipedia.org/wiki/Xargs#The_separator_propet
Ole Tange

Câu trả lời:


19

Phiên bản ngắn:

rm *\([1-9]\)*

Đừng tẩu ls đến xargs. Thay vào đó, đường ống find ... -print0 đến xargs -0, để tránh những vấn đề như vậy.

find . -maxdepth 1 -name '*([1-9])*' -print0 | xargs -0 rm

... có thể được viết là:

find . -maxdepth 1 -name '*([1-9])*' -exec rm {} \;

và:

find . -maxdepth 1 -name '*([1-9])*' -delete

mà có thể rút ngắn hơn nữa chỉ rm với một ký tự đại diện.


Thông thường, lsfind tên tệp riêng biệt với dòng mới, nhưng xargs chia đầu vào của nó theo dòng mới hoặc là không gian, dẫn đến hành vi bạn nhìn thấy.

Có thể nói xargs chỉ phân chia theo dòng mới, nhưng các tệp có thể có dòng mới trong tên của họ quá. Trên thực tế, trên Linux và BSD, chỉ có nhân vật không được phép "vô giá trị" hoặc byte không - vì vậy đó là những gì bạn nên sử dụng trong những trường hợp như vậy.

Trong ví dụ 2 ở trên, -print0 kể find để phân tách tên tệp bằng byte rỗng; giống với xargs -0. (Một vài công cụ khác cũng có các tùy chọn tương tự, chẳng hạn như sort -z hoặc là grep -zZ.)

"Phiên bản ngắn" sử dụng ký tự đại diện đơn giản ("mẫu" trong bash hướng dẫn sử dụng - xem phần "Mở rộng tên đường dẫn").


1
Và để an toàn, tốt hơn là sử dụng *" "\\([1-9]\\).* để chỉ các tệp có khoảng trắng trước số paren'd trước khoảng thời gian (a, để công bằng) bị xóa.
Ignacio Vazquez-Abrams

Không quen thuộc lắm với cú pháp này, nhưng dựa trên các upvote tôi đã thử và bạn biết gì ... nó đã hoạt động! Cảm ơn!
Jeff

1
+1. -print0 là điều cần thiết cho đường ống chính xác đến xargs.
Chris W. Rea
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.