Câu trả lời:
Công việc diễn giải biểu tượng đường ống như một hướng dẫn để chạy nhiều quy trình và đưa đầu ra của một quy trình vào đầu vào của một quy trình khác là trách nhiệm của trình bao (/ bin / sh hoặc tương đương).
Trong ví dụ của bạn, bạn có thể chọn sử dụng trình bao cấp cao nhất của mình để thực hiện đường ống như vậy:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
Về mặt hiệu quả, kết quả này tiêu tốn một lần tìm kiếm, nhiều lần gọi zcat và một lần gọi agrep.
Điều này sẽ chỉ dẫn đến một quá trình agrep duy nhất được sinh ra, nó sẽ xử lý tất cả đầu ra được tạo ra bởi nhiều yêu cầu của zcat.
Nếu bạn vì lý do nào đó muốn gọi agrep nhiều lần, bạn có thể làm:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
Điều này xây dựng một danh sách các lệnh sử dụng các đường ống để thực thi, sau đó gửi chúng đến một vỏ mới để thực sự được thực thi. (Bỏ qua "| sh" cuối cùng là một cách hay để gỡ lỗi hoặc thực hiện các dòng lệnh khô như thế này.)
Về mặt hiệu quả, kết quả này tiêu tốn một lần tìm kiếm, một lần gọi sh, nhiều lần gọi zcat và nhiều lần gọi agrep.
Giải pháp hiệu quả nhất về số lượng các lệnh truyền lệnh là gợi ý từ Paul Tomblin:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... Chi phí cho một lần gọi tìm kiếm, một lần gọi xargs, một vài lần gọi zcat và một lần gọi agrep.
-exec sh -c "… | … " \;
.
giải pháp rất dễ dàng: thực hiện thông qua sh
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
-c
tùy chọn. Nếu không, bạn sẽ nhận được một No such file or directory
thông báo lỗi khó hiểu .
find -type f -name '*.mdds' -exec sh -c "echo {} | sed -e 's/_[0-9]\+//g' | xargs mv {}" \;
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
Bạn cũng có thể dẫn đến một while
vòng lặp có thể thực hiện nhiều hành động trên tệp find
định vị. Vì vậy, đây là một cái để tìm trong jar
kho lưu trữ cho một tệp lớp java đã cho trong thư mục với một bản phân phối lớn của jar
các tệp
find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done
điểm mấu chốt là while
vòng lặp chứa nhiều lệnh tham chiếu đến tên tệp được phân tách bằng dấu chấm phẩy và các lệnh này có thể bao gồm các đường ống. Vì vậy, trong ví dụ đó, tôi lặp lại tên của tệp phù hợp, sau đó liệt kê những gì trong bộ lọc lưu trữ cho một tên lớp đã cho. Đầu ra trông như sau:
/usr/lib/eclipse/plugins/org.eclipse.core.contenttype.source_3.4.1.R35x_v20090826-0451.jar /usr/lib/eclipse/plugins/org.eclipse.core.databinding.observable_1.2009090 .jar org / eclipse / core / databinding / obsable / list / IObservableList. class /usr/lib/eclipse/plugins/org.eclipse.search.source_3.5.1.r351_v20090708-0800.jar / usr / lib / eclipse / plugins org.eclipse.jdt.apt.core.source_3.3.202.R35x_v20091130-2300.jar /usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar / usr / lib / eclipse org.eclipse.help.appserver_3.1.400.v20090429_1800.jar
trong shell bash của tôi (xubfox10.04 / xfce), nó thực sự làm cho tên lớp được khớp được in đậm làm fgrep
nổi bật chuỗi khớp; điều này làm cho nó thực sự dễ dàng để quét xuống danh sách hàng trăm jar
tệp đã được tìm kiếm và dễ dàng xem bất kỳ trận đấu nào.
trên windows bạn có thể làm điều tương tự với:
for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList
lưu ý rằng trong các cửa sổ, dấu phân cách lệnh là '&' không ';' và rằng '@' triệt tiêu tiếng vang của lệnh để đưa ra một đầu ra gọn gàng giống như đầu ra tìm linux ở trên; mặc dù findstr
không làm cho chuỗi phù hợp được in đậm nên bạn phải nhìn kỹ hơn một chút ở đầu ra để xem tên lớp phù hợp. Hóa ra lệnh 'for' của windows biết khá nhiều thủ thuật như lặp qua các tệp văn bản ...
thưởng thức
Tôi thấy rằng việc chạy lệnh shell shell (sh -c) hoạt động tốt nhất, ví dụ:
find -name 'file_*' -follow -type f -exec bash -c "zcat \"{}\" | agrep -dEOE 'grep'" \;
Nếu bạn đang tìm kiếm một giải pháp thay thế đơn giản, điều này có thể được thực hiện bằng cách sử dụng một vòng lặp:
for i in $(find -name 'file_*' -follow -type f);do zcat $i | agrep -dEOE 'grep');done
hoặc, hình thức tổng quát và dễ hiểu hơn:
for i in $(YOUR_FIND_COMMAND);do YOUR_EXEC_COMMAND_AND_PIPES );done
và thay thế bất kỳ {} bằng $ i trong YOU_EXEC_COMMAND_AND_PIPES