Це не працює. Чи можна це зробити в пошуку? Або мені потрібно 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