`xargs` với khoảng trắng trong tên tệp


7

Tôi đang cố gắng chỉ liệt kê các tệp không phải hình ảnh , chỉ tìm kiếm trong 500 tệp gần đây nhất. Vì vậy, tôi chạy

ls -t | head -500 | file | grep -v 'image'

Điều đó không đúng: nó hiển thị một thông báo trợ giúp. Thay đổi nó thành

ls -t | head -500 | xargs file | grep -v 'image'

Tôi bây giờ đôi khi nhận được đầu ra tôi muốn, nhưng nếu tên tập tin có khoảng trống trong it-ví dụ Plutonian\ Nights\ -\ Sun\ Ra.mp3-Sau đó xargssẽ chạy file Plutonian, file Nightsvv


Làm thế nào để tôi có thể giúp xargsnhìn thấy các không gian, hoặc nói cách khác là hoàn thành những gì tôi đang cố gắng thực hiện?


Trong các xargstriển khai phổ biến , ví dụ, dấu phân cách có thể được thay đổi '\n'. Điều này thường hữu ích khi đầu vào không được tạo bởi find. Xem -d(GNU) và -E(OSX)
MattBianco

Câu trả lời:


5

Sử dụng xargs, nó có thể được thực hiện theo cách này:

find . -type f -print0 | xargs -0 file | grep -v 'image' 

Nhưng xargslà như vậy ngày hôm qua. Những đứa trẻ mát mẻ sử dụng parallelngày hôm nay. Sử dụng song song, nó sẽ là:

find . -type f | parallel file | grep -v 'image'

Xem. Không sử dụng -print0 và -0. parallellà thực sự thông minh của chính nó.

CẬP NHẬT

Để chỉ liệt kê 500 tệp gần đây nhất, lệnh của bạn sẽ là:

ls -1t | head -500 | parallel file {} | grep -v image

Quan trọng

Trong trường hợp song song của bạn là cũ và cú pháp trên không hoạt động, thì hãy cài đặt phiên bản song song mới như được giải thích tại đây: http://www.gnu.org/software/abul/abul_tutorial.html


2

Sử dụng tùy chọn "find" với "-print0" và chuyển đầu ra thành "xargs" với tùy chọn "-0".

Mặc dù tôi biết (và sử dụng) kỹ thuật này, tôi thấy rằng người dùng @Jens đã trả lời một câu hỏi tương tự, nơi bạn có thể tìm thêm Chi tiết:

/programming/16758525/use-xargs-with-filenames-contained-whitespaces


1
Bạn có trái cây treo thấp. Làm thế nào để bạn chỉ tìm kiếm 500 tập tin gần đây nhất?
G-Man nói 'Phục hồi Monica'

1

Tôi có hai gợi ý thô thiển có thể giúp ích. Không cảm thấy đặc biệt thỏa mãn mặc dù, vì vậy có lẽ một cái gì đó tốt hơn sẽ xuất hiện.

Đầu tiên, sử dụng sed để thêm dấu ngoặc kép vào mọi thứ, vì vậy bạn sẽ chỉ gặp rắc rối nếu có dấu ngoặc kép trong tên tệp như

ls -t | head -500 | sed -e 's/\(.*\)/"\1"/' | xargs file | grep -v 'image'

Cách khác là sử dụng ls để tìm thứ 501 gần đây nhất sau đó sử dụng find để có được những thứ mới hơn như

find -newer $(ls -t | head -501 | tail -1) -type f -exec file {} \; | grep -v image

1
Miễn là chúng tôi sẽ phân tích đầu ra của ls, tôi tin rằng đoạn mã đầu tiên của bạn sẽ được cải thiện bằng cách thay thế dòng mới bằng null ( tr \\n \\0) và sử dụng xargs -0.
dhag

1

Để được tư vấn chung về việc xử lý tên tệp có khả năng chứa khoảng trắng, hãy xem Tại sao tập lệnh shell của tôi bị nghẹt trên khoảng trắng hoặc các ký tự đặc biệt khác?

Khó khăn với những gì bạn đang cố gắng làm là không có cách nào hay để liệt kê N tệp gần đây nhất với các công cụ tiêu chuẩn.

Cách dễ nhất để làm những gì bạn đang làm ở đây là sử dụng zsh làm vỏ của bạn. Nó có vòng loại toàn cầu để sắp xếp các tập tin theo ngày. Để chạy filetrên 500 tệp gần đây nhất:

file *(om[1,500])

Với filetiện ích Linux , vượt qua -ihoặc --mime-typetùy chọn để có được đầu ra dễ phân tích hơn. Các tập tin hình ảnh được xác định bởi các dòng kết thúc bằng image/something.

file --mime-type *(om[1,500]) | sed -n 's~: *image/[^ ]*$~~p'

Nếu bạn cần đối phó hoàn toàn với tất cả các tên tệp, bao gồm cả những tên có dòng mới trong tên của chúng, hãy sử dụng -0tùy chọn cho đầu ra được phân tách bằng null. Các phiên bản gần đây của GNU sed có thể sử dụng byte rỗng làm dấu phân cách bản ghi thay vì dòng mới.

file --mime-type -- *(om[1,500]) | sed -zn 's~: *image/[^ ]*$~~p'

Nếu bạn không có zsh, bạn có thể sử dụng lsvà đối phó với các tên tệp có chứa khoảng trắng nhưng không phải là dòng mới hoặc dấu cách bằng cách chuyển -L1tùy chọn đến file. Điều này được gọi filetrên một tệp tại một thời điểm, vì vậy nó hơi chậm.

ls -t | head -n 500 | xargs -L1 file --mime-type -- | sed -n 's~: *image/[^ ]*$~~p'

-1

Bạn có thể thử

printf "%s\0" $(ls -t | head -500) | xargs -0 file | grep -v image

Điều này buộc xargs thành null-delimit các đối số tên tệp.


1
Khi tôi thử điều này với một tệp có khoảng trắng trong tên của nó (ví dụ Sun Ra:), tôi nhận được Sun\0Ra\0, vì vậy điều này không giải quyết được vấn đề.
G-Man nói 'Phục hồi Monica'

Xin lỗi, tôi đã bỏ lỡ một bộ trích dẫn:
doneal24

1
Điều này sẽ không hoạt động; printfsẽ coi mỗi từ được phân tách bằng dấu cách là một đối số. Bạn có thể kiểm tra điều này với printf "%s\n" $(printf "file #1\nfile2\n").
dhag

@dhag: Vâng, tôi đã chỉ ra 40 phút trước.
G-Man nói 'Phục hồi Monica'

1
@Doug: Nếu bạn định đề xuất một câu trả lời bổ sung cho câu trả lời của Eric, thì sẽ hợp lý hơn khi bình luận về câu trả lời của Eric - và giải thích tại sao câu trả lời của bạn tốt hơn câu trả lời của anh ấy. Ngoài ra, bạn đã bỏ lỡ imagemột phần của câu hỏi.
G-Man nói 'Phục hồi Monica'
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.