Как включить трубу | в моей команде linux find -exec?

Это не работает. Можно ли это сделать в поиске? Или мне нужно xargs?

find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
232
0
122 493
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

Надеемся избежать -print и xargs по соображениям эффективности. Может быть, это действительно моя проблема: find не может обрабатывать команды через конвейер через -exec

someguy 21.11.2008 01:09

Это не работает с файлами, в именах которых есть пробелы; чтобы исправить, замените -print на -print0 и добавьте параметр -0 в xargs

Adam Rosenfield 21.11.2008 01:44

@someguy - Что? Избегаете xargs из соображений эффективности? Вызов одного экземпляра zcat и передача ему списка из нескольких файлов далеко более эффективен, чем выполнение его нового экземпляра для каждого найденного файла.

Sherm Pendley 21.11.2008 01:44

@ Адам - ​​Я внес предложенные вами изменения. В 99% случаев, когда я делаю находки, они находятся в моих каталогах с исходным кодом, и ни в одном из файлов там нет пробелов, поэтому я не беспокоюсь о print0. С другой стороны, теперь в моем каталоге документов я помню файл print0.

Paul Tomblin 21.11.2008 18:12

решение простое: выполнить через sh

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

То, что OP пытался выполнить, можно встретить с помощью приведенных выше предложений, но это тот, который на самом деле отвечает на заданный вопрос. Для этого есть причины - exec намного мощнее, чем просто работа с файлами, возвращаемыми с помощью find, особенно в сочетании с test. Например: найдите geda-gaf / -type d -exec bash -c 'DIR = {}; [[$ (найти $ DIR -maxdepth 1 | xargs grep -i spice | wc -l) -ge 5]] && echo $ DIR '\; Вернет все каталоги в пути поиска, которые содержат в общей сложности более 5 строк среди всех файлов в этом каталоге, содержащих слово spice

swarfrat 27.05.2012 23:00

Лучший ответ. Grepping всего вывода (как предполагают другие ответы) - это не то же самое, что grep each file. Совет: вместо sh вы можете использовать любую другую оболочку, какую захотите (я пробовал это с помощью bash, и она работает нормально).

pagliuca 23.11.2012 22:15

Не упускайте из виду вариант -c. В противном случае вы получите сбивающее с толку сообщение об ошибке No such file or directory.

asmaier 06.12.2013 16:22

вот отличная замена ps, которая использует find с конвейером внутри оболочки exec'd: / usr / bin / find / proc -mindepth 1 -maxdepth 1 -type d -regex '. * / [0-9] +' - print -exec bash -c "cat {} / cmdline | tr '\\ 0' ''; echo" \;

parity3 02.08.2014 06:11

Пример поиска файлов и их переименования в sed с использованием регулярного выражения find -type f -name '*.mdds' -exec sh -c "echo {} | sed -e 's/_[0-9]\+//g' | xargs mv {}" \;

Rostfrei 04.11.2015 10:06
Ответ принят как подходящий

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

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

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

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

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

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

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

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

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

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

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

... что стоит одного вызова find, одного вызова xargs, нескольких вызовов zcat и одного вызова согласования.

Еще одним преимуществом xargs является то, что вы можете еще больше ускорить его с помощью современных многоядерных процессоров, используя переключатель -P (-P 0).

flolo 21.11.2008 02:03

Да, ключ -P действительно хороший способ ускорить выполнение в целом. К сожалению, вы рискуете, что выходные данные параллельных процессов zcat будут переданы по конвейеру с чередованием согласования, что повлияет на результат. Этот эффект можно продемонстрировать с помощью: echo -e "1 \ n2" | xargs -P 0 -n 1 да | уникальный

Rolf W. Rasmussen 21.11.2008 02:57

@ Адам, я внес предложенные вами изменения.

Paul Tomblin 21.11.2008 18:09

для которой вы можете установить великолепную команду xjobs (изначально из Solaris)

sehe 14.04.2011 02:26

Что за зверь, printf с sh. Ты жжешь.

Javier Diaz 22.01.2013 15:29

Более простой и общий ответ на stackoverflow.com/a/21825690/42973: -exec sh -c "… | … " \;.

Eric O Lebigot 26.04.2015 04:04

Вы также можете подключиться к циклу 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 org / eclipse / core / databinding / наблюдаемый / список / 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, которые были найдены, и легко увидеть любые совпадения.

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

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

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

наслаждаться

Если вы ищете простую альтернативу, это можно сделать с помощью цикла:

for i in $(find -name 'file_*' -follow -type f); do
  zcat $i | agrep -dEOE 'grep'
done

или, в более общем и понятном виде:

for i in $(YOUR_FIND_COMMAND); do
  YOUR_EXEC_COMMAND_AND_PIPES
done

и замените любой {} на $ i в YOUR_EXEC_COMMAND_AND_PIPES

Я обнаружил, что лучше всего работает строковая команда оболочки (sh -c), например:

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

Другие вопросы по теме