Це не працює. Чи можна це зробити в пошуку? Або мені потрібно xargs?
find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
Це не працює. Чи можна це зробити в пошуку? Або мені потрібно 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'
З точки зору ефективності цей результат коштує одного виклику знаходження, численних викликів zcat та одного виклику agrep.
Це призвело б до породження лише одного узгодженого процесу, який обробив би всі результати, отримані численними викликами zcat.
Якщо ви з якоїсь причини хочете кілька разів викликати agrep, ви можете зробити:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
Це створює перелік команд, які використовують труби для виконання, а потім надсилає їх у новий оболонку для фактичного виконання. (Пропуск остаточного "| sh" - хороший спосіб налагодження або виконання сухих запусків командних рядків типу цього.)
З точки зору ефективності цей результат коштує одного виклику знаходження, одного виклику sh, численних викликів zcat та численних викликів agrep.
Найбільш ефективним рішенням щодо кількості викликів команд є пропозиція Пола Томбліна:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... що коштує одного виклику знаходження, одного виклику xargs, декількох викликів zcat та одного виклику agrep.
-exec sh -c "… | … " \;.
рішення просте: виконати через sh
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
-cваріант. Інакше ви отримаєте дивовижне No such file or directoryповідомлення про помилку.
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'
Ви також можете передати 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
в моїй баш-оболонці (xubuntu10.04 / xfce) вона дійсно робить зіставлене ім’я класу жирним, як fgrepпідкреслює відповідність рядка; це дозволяє дуже легко просканувати список сотень jarфайлів, які шукали, і легко переглядати будь-які збіги.
у вікнах ви можете зробити те саме:
for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList
зауважте, що в Windows на цьому розділювачі команд є "& 'not'; ' і що "@" пригнічує відлуння команди, щоб дати акуратний висновок так само, як висновок Linux знайти вище; хоча findstrне робимо зіставлену рядок жирною, тому вам доведеться трохи ближче подивитися на висновок, щоб побачити відповідне ім'я класу. Виявляється, команда windows 'for' знає досить багато хитрощів, таких як прокручування текстових файлів ...
насолоджуватися
Я виявив, що найкраще працює команда string shell (sh -c), наприклад:
find -name 'file_*' -follow -type f -exec bash -c "zcat \"{}\" | agrep -dEOE 'grep'" \;
Якщо ви шукаєте просту альтернативу, це можна зробити за допомогою циклу:
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