web-development-kb-asia.site

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

Tôi đang cố gắng xây dựng một lệnh find để xử lý một loạt các tệp trong một thư mục bằng hai tệp thực thi khác nhau. Không may, -exec on find không cho phép sử dụng đường ống hoặc thậm chí \| bởi vì Shell diễn giải ký tự đó trước.

Đâ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 find):

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

Thử đi

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 exec của mình vào trong tập lệnh sh và sau đó thực hiện:

find -exec some_script {} \;
79
Martin Marconcini

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ễ thích nghi hơn một chút (các đối số -print0 và -0 là cần thiết để đối phó với tên tệp chứa khoảng trống)

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

12
Palmin

Với -exec bạ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 các lệnh Shell tùy ý. Để phá vỡ điều này, bạn có thể sử dụng sh -c '<Shell command>'.

Xin lưu ý rằng việc sử dụng -exec 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 điều này. (Ví dụ: bằng cách di chuyển grep bên ngoài -exec hoặc dẫn các kết quả của find đến xargs theo đề xuất của Palmin .)

3
mweerden

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

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

Vì đ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

Đặt grep của bạn vào kết quả của find -exec.

1
Xetius

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

Sử dụng phần mở rộng tùy chọn Shell, bạn có thể làm một cái gì đó tương tự như thế này để thực hiện tìm công cụ exec và sau đó chuyển nó sang sh.

[email protected] findtest # find -type f -exec echo ls $"|" cat \;|sh
filename


[email protected] findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

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

0
linuxgeek