2008-11-20 2 views

ответ

109

Работа интерпретации символа трубы в качестве инструкции для запуска нескольких процессов и трубы выход одного процесса на вход другой процесс является обязанностью оболочки (/ bin/sh или эквивалентной).

В вашем примере вы можете выбрать либо использовать верхнюю оболочку уровня для выполнения трубопроводов следующим образом:

find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep' 

С точки зрения эффективности это приводит расходы один вызов найти, многочисленные инвокации zcat, и один вызывание agrep.

Это приведет к появлению только одного процесса агрегирования, который будет обрабатывать весь вывод, созданный многочисленными вызовами zcat.

Если вы по какой-то причине хотели бы вызвать agrep несколько раз, вы можете сделать:

find . -name 'file_*' -follow -type f \ 
    -printf "zcat %p | agrep -dEOE 'grep'\n" | sh 

Это создает список команд, использующие трубы для выполнения, а затем отправляет их в новую оболочку на самом деле выполняться , (Опущение окончательного «| sh» - отличный способ отладки или выполнения сухих пробегов командных линий, подобных этому.)

С точки зрения эффективности эти результаты обходятся одним вызовом поиска, одним вызовом sh, многочисленными вызовами zcat и многочисленные призывы agrep.

Наиболее эффективным решением с точки зрения количества командных вызовов является предложение от Пола Tomblin:

find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep' 

... который стоит один вызов найти, один вызов xargs, несколько инвокации zcat и один вызов agrep.

13
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep' 
+0

Надеясь избежать -Print и xargs по соображениям эффективности. Возможно, это действительно моя проблема: find не может обрабатывать команды с каналами через -exec – someguy 2008-11-20 22:09:18

+0

Это не работает с файлами с пробелами в их именах; исправить, заменить -print на -print0 и добавить параметр -0 в xargs – 2008-11-20 22:44:05

+2

@someguy - Wha? Избегайте xargs по соображениям эффективности? Вызов одного экземпляра zcat и передача его списка из нескольких файлов * намного эффективнее, чем запуск нового экземпляра для каждого найденного файла. – 2008-11-20 22:44:38

190

решение легко: выполнить с помощью ш

... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \; 
8

Вы также можете подключить цикл while, который может выполнять несколько действий над файлом, который find находит. Так вот один для поиска в jar архивы для данного файла класса Java в папке с большим дистрибутивом из jar файлов

find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done 

ключевой момент в том, что цикл while содержит несколько команд, ссылающихся переданному в имени файла, разделенных точка с запятой, и эти команды могут включать в себя трубы. Поэтому в этом примере я повторяю имя соответствующего файла, а затем перечисляю то, что находится в фильтрации архива для данного имени класса. Вывод выглядит следующим образом:

/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.2.0.M20090902-0800.jar орга/затмение/ядро ​​/ привязок/наблюдаемый/список/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.банк /usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar /usr/lib/eclipse/plugins/org.eclipse.help.appserver_3.1.400.v20090429_1800.jar

в моей оболочке bash (xubuntu10.04/xfce) действительно делает совпадающее имя класса жирным, так как fgrep выделяет совпадающую строку; это позволяет легко просканировать список сотен jar файлов, которые были найдены, и легко увидеть любые совпадения.

на окнах вы можете сделать то же самое с:

for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList 

отметить, что в том, что на окнах команда разделитель «&» не «;» и что «@» подавляет эхо команды, чтобы дать аккуратный вывод, как и вывод вывода linux выше; хотя findstr не делает выделенную строку полужирным, поэтому вам нужно немного подойти к выходу, чтобы увидеть совпадающее имя класса. Оказывается, что окна «для» команды знает немало трюков, таких как перекручивание через текстовые файлы ...

пользуются

Смежные вопросы