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
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 {} \;
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.
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 .)
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
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.
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.