Làm cách nào để sử dụng một đường ống trong tham số thực thi cho lệnh tìm?


77

Tôi đang cố gắng tạo một lệnh find để xử lý một loạt các tệp trong một thư mục bằng cách sử dụng hai tệp thực thi khác nhau. Thật không may, -exectrên tìm thấy không cho phép sử dụng đường ống hoặc thậm chí \|vì trình bao thông dịch ký tự đó trước.

Dưới đây là cụ thể những gì tôi đang cố gắng thực hiện (không hoạt động vì đường ống kết thúc lệnh tìm):

find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print

Câu trả lời:


87

Thử cái này

find /path/to/jpgs -type f -exec sh -c 'jhead -v {} | grep 123' \; -print

Ngoài ra, bạn có thể thử nhúng câu lệnh thực thi của mình vào trong một tập lệnh sh và sau đó thực hiện:

find -exec some_script {} \;

15

Một cách tiếp cận hơi khác sẽ là sử dụng xargs:

find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123

mà tôi luôn thấy dễ hiểu và dễ điều chỉnh hơn một chút (các đối số -print0 và -0 là cần thiết để đối phó với các tên tệp chứa khoảng trống)

Điều này có thể (không được thử nghiệm) hiệu quả hơn so với sử dụng -exec vì nó sẽ chuyển danh sách tệp đến xargs và xargs đảm bảo rằng dòng lệnh jhead không quá dài.


4
Vấn đề với việc sử dụng xargs ở đây là tôi cần tên của tệp phù hợp. Lệnh này tìm thấy các kết quả phù hợp, nhưng tôi không biết tệp nào phù hợp.
hoyhoy 15/09/08

4

Với -execbạn chỉ có thể chạy một tệp thực thi duy nhất với một số đối số, không phải lệnh shell tùy ý. Để phá vỡ điều này, bạn có thể sử dụng sh -c '<shell command>'.

Lưu ý rằng việc sử dụng -execlà khá kém hiệu quả. Đối với mỗi tệp được tìm thấy, lệnh phải được thực hiện lại. Sẽ hiệu quả hơn nếu bạn có thể tránh được điều này. (Ví dụ: bằng cách di chuyển ra grepbên ngoài -exechoặc đường ống kết quả của findđến xargstheo đề xuất của Palmin .)


1
Một cách khác để tránh sự kém hiệu quả của nhiều quy trình trong trường hợp chung là sử dụng xargs. Nếu bạn cần các quy trình riêng biệt, bạn có thể sử dụng tùy chọn -i. Tôi thấy xargs phù hợp hơn với mô hình Unix.
Jon Ericson

1
AOL khi sử dụng xargs. mweerden, có lẽ bạn nên thay đổi đoạn cuối của mình bằng cách tính đến sự tồn tại của xargs. Cũng lưu ý cờ -0 tồn tại trong cả hai findxargs.
tzot 11/10/08

3

Sử dụng findlệnh cho loại tác vụ này có thể không phải là giải pháp thay thế tốt nhất. Tôi thường xuyên sử dụng lệnh sau để tìm các tệp có chứa thông tin được yêu cầu:

for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done

1

Khi điều này xuất ra một danh sách, bạn sẽ không:

find /path/to/jpgs -type f -exec jhead -v {} \; | grep 123

hoặc là

find /path/to/jpgs -type f -print -exec jhead -v {} \; | grep 123

Đưa grep của bạn vào kết quả tìm kiếm -exec.


Điều đó không hiệu quả vì tôi cần -print để hoạt động. Nếu grep trả về thành công, hãy tìm bản in tên tệp, nếu không thì không.
hoyhoy 15/09/08

0

Có một cách khác mà bạn có thể làm nhưng nó cũng khá là kiểu ổ chuột.

Sử dụng tùy chọn shell extquote, bạn có thể làm điều gì đó tương tự như thế này để tìm nội dung thực thi và sau đó chuyển nó đến sh.

root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename


root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

Tôi chỉ nghĩ rằng tôi sẽ thêm điều đó bởi vì ít nhất theo cách tôi hình dung nó, nó gần với câu hỏi ban đầu của OP về việc sử dụng các đường ống trong thi hành.

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.