Это не работает Можно ли это сделать в find? Или мне нужно xargs?
find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
источник
Это не работает Можно ли это сделать в find? Или мне нужно xargs?
find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
Ответственность за интерпретацию символа канала как инструкции для запуска нескольких процессов и передачи результатов одного процесса на вход другого процесса лежит на оболочке (/ bin / sh или эквивалентной).
В вашем примере вы можете выбрать использование оболочки верхнего уровня для выполнения конвейера следующим образом:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
С точки зрения эффективности этот результат стоит одного вызова find, многочисленных вызовов zcat и одного вызова agrep.
Это приведет к появлению только одного agrep-процесса, который обработает весь вывод, полученный при многочисленных вызовах zcat.
Если по какой-то причине вы хотите вызывать agrep несколько раз, вы можете сделать:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
Это создает список команд, использующих каналы для выполнения, а затем отправляет их новой оболочке для фактического выполнения. (Пропуск финального «| sh» - это хороший способ отладки или выполнения пробных запусков командных строк, подобных этой.)
С точки зрения эффективности этот результат стоит одного вызова find, одного вызова sh, многочисленных вызовов zcat и многочисленных вызовов agrep.
Наиболее эффективным решением с точки зрения количества вызовов команд является предложение от Пола Томблина:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... который стоит один вызов find, один вызов xargs, несколько вызовов zcat и один вызов agrep.
-exec sh -c "… | … " \;
.решение простое: выполнить через sh
источник
-c
опцию. В противном случае вы получите удивительноеNo such file or directory
сообщение об ошибке.find -type f -name '*.mdds' -exec sh -c "echo {} | sed -e 's/_[0-9]\+//g' | xargs mv {}" \;
источник
Вы также можете передать в
while
цикл, который может выполнять несколько действий с файлом, которыйfind
находится. Так что вот один для поиска вjar
архивах для данного файла класса Java в папке с большим дистрибутивомjar
файловКлючевым моментом является то, что
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.M2009090-0800 .jar org / eclipse / core / привязка данных / наблюдаемый / список / 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 / plugins org.eclipse.help.appserver_3.1.400.v20090429_1800.jar
в моей оболочке bash (xubuntu10.04 / xfce) это действительно делает сопоставленное имя класса полужирным, поскольку
fgrep
выделяет соответствующую строку; это позволяет легко просматривать список сотенjar
файлов, которые были найдены, и легко видеть любые совпадения.на окнах вы можете сделать то же самое с:
обратите внимание, что в Windows разделителем команд является '&' not ';' и что '@' подавляет эхо команды, чтобы выдать аккуратный вывод точно так же, как вывод linux find выше; хотя
findstr
это не делает сопоставляемую строку жирным шрифтом, поэтому вам нужно взглянуть немного ближе к выводу, чтобы увидеть соответствующее имя класса. Оказывается, команда windows 'for' знает немало хитростей, таких как циклический просмотр текстовых файлов ...наслаждаться
источник
Я обнаружил, что лучше всего работает команда string shell (sh -c), например:
источник
Если вы ищете простую альтернативу, это можно сделать с помощью цикла:
или, более общая и простая для понимания форма:
и замените любой {} на $ i в YOUR_EXEC_COMMAND_AND_PIPES
источник