14 ответов:
трубопроводы в другой процесс (хотя это не будет выполнять то, что вы сказали, что вы пытаетесь сделать):
command1 | command2это отправит выходные данные command1 в качестве входных данных command2
-execнаfind(этот будет делать то, что вы хотите сделать, но относящиеся кfind)find . -name '*.foo' -exec cat {} \;(между
findи-execнайти предикаты, которые вы уже использовали.{}заменить конкретный файл, который вы нашли в команде (cat {}в данном случае); the\;конец .)отправить выход из одного процесса в качестве аргументов командной строки в другой процесс
command2 `command1`например:
cat `find . -name '*.foo' -print`(обратите внимание, что это обратные кавычки, а не обычные кавычки (под Тильдой ~ на моей клавиатуре).) Это отправит вывод
command1наcommand2в качестве аргументов командной строки. Обратите внимание, что имена файлов, содержащие однако пробелы (новые строки и т. д.) будут разбиты на отдельные аргументы.
find . -print | xargs grep somethingесли вы на Linux или у вас есть GNU
findиxargs, а затем использовать-print0Сfindи-0Сxargsдля обработки имен файлов, содержащих пробелы и другие нечетные символы.если вы не хотите имена файлов-только текст - то добавьте соответствующую опцию в
grep(обычно-hсправочник 'заголовки'). Чтобы абсолютно гарантировать, что имя файла печатается с помощьюgrep(даже если найден только один файл или последний вызовgrepдается только 1 имя файла), затем добавить/dev/nullдоxargsкомандная строка, так что всегда будет по крайней мере два имени файла.
обратите внимание, что POSIX 2008 добавил
+маркерfindчто означает, что теперь он автоматически группирует столько файлов, сколько разумно в одно выполнение команды, очень похоже наxargsделает, но с рядом преимуществ:
- вам не нужно беспокоиться о нечетных символах в файле имена.
- вам не нужно беспокоиться о том, что команда вызывается с нулевыми именами файлов.
обе эти проблемы с
xargsбез . Следовательно, вы могли бы разумно написать:find . -exec grep something {} +
есть несколько способов передать список файлов, возвращенных до
catкоманда, хотя технически не все используют трубопроводы, и ни один на самом деле трубы непосредственно кcat.
самый простой способ-это использовать обратные кавычки (
`):cat `find [whatever]`это принимает выход
findи эффективно помещает его в командной строкеcat. Это не работает хорошо, еслиfindслишком много выходных (больше, чем может поместиться в командной строке) или если на выходе есть специальные символы (например, пробелы).в некоторых оболочках, в том числе
bashможно использовать$()вместо обратные кавычки :cat $(find [whatever])это менее портативно, но нестабильно. Кроме того, он имеет почти те же предостережения, что и backticks.
потому что выполнение других команд на том, что было найдено, является общим использованием для
find, имеет-execдействие, которое выполняет команду для каждого файла это находки:find [whatever] -exec cat {} \;The
{}является заполнителем для имени файла, а\;отмечает конец команды (после .)это будет работать
catодин раз для каждого отдельного файла вместо запуска одного экземпляраcatпередача ему нескольких имен файлов, которые могут быть неэффективными и могут не иметь поведения, которое вы хотите для некоторых команд (хотя это нормально дляcat). Синтаксис также неудобен для ввода -- you нужно избежать точки с запятой, потому что точка с запятой является особенной для оболочки!некоторые версии
find(особенно версия GNU) позволяет заменить;С+использовать-execрежим добавления для запуска меньшего количества экземпляровcat:find [whatever] -exec cat {} +это передаст несколько имен файлов для каждого вызова
cat, который может быть более эффективным.обратите внимание, что это не гарантированно использовать один вызов, однако. Если командная строка будет слишком длинной, то аргументы будут распределены по нескольким вызовам
cat. Ибоcatэто, вероятно, не имеет большого значения, но для некоторых других команд это может изменить поведение нежелательным образом. В системах Linux ограничение длины командной строки довольно велико, поэтому разбиение на несколько вызовов довольно редко по сравнению с некоторыми другими ОС.классический/портативный подход заключается в использовании
xargs:find [whatever] | xargs cat
xargsвыполняет указанную команду (catв данном случае), и добавляет аргументы, основанные на том, что он читает из stdin. Так же, как-execС+, при необходимости это приведет к разрыву командной строки. То есть, еслиfindпроизводит слишком много вывода, он будет работатьcatнесколько раз. Как уже упоминалось в разделе о-execранее, есть некоторые команды, где это разделение может привести к различному поведению. Обратите внимание, что с помощьюxargsкак это проблемы с пробелами в именах файлов, какxargsпросто использует пробелы в качестве разделителя.самый надежный, портативный и эффективный метод также использует
xargs:find [whatever] -print0 | xargs -0 catThe
-print0флаг говоритfindиспользовать(нулевой символ) разделители между именами и-0флаг говоритxargsожидать, что этиразделители. Это имеет в значительной степени идентичное поведение-exec...+подход, хотя и более портативный (но, к сожалению, более подробно).
для достижения этого (с помощью bash) я бы сделал следующее:
cat $(find . -name '*.foo')Это известно как" подстановка команд", и по умолчанию он удаляет подачу строки, что действительно удобно !
более подробная информация здесь
звучит как работа для сценария оболочки для меня:
for file in 'find -name *.xml' do grep 'hello' file doneили что-то подобное
вот мой способ найти имена файлов, которые содержат некоторый контент, который меня интересует, просто одна строка bash, которая также хорошо обрабатывает пробелы в именах файлов:
find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done
Я использую что-то вроде этого:
find . -name <filename> -print0 | xargs -0 cat | grep <word2search4>"
-print0" аргумент "найти" и "-0" аргумент для "xargs" необходим для правильной обработки пробелов в путях/именах файлов.
команда find имеет аргумент-exec, который вы можете использовать для таких вещей, вы можете просто сделать grep напрямую, используя это.
например (отсюда, другие хорошие примеры на эту страницу):
find . -exec grep "www.athabasca" '{}' \; -print
в bash было бы уместно следующее:
find /dir -type f -print0 | xargs -0i cat {} | grep whateverэто позволит найти все файлы в
/dirкаталог, и безопасно передавать имена файлов вxargs, который будет безопасно управлятьgrep.пропуск
xargsне очень хорошая идея, если у вас есть много тысяч файлов в/dir;catсломается из-за чрезмерной длины списка аргументов.xargsразберется, что все для вас.The до
findсетки с доxargsдля правильной обработки имен файлов с пробелами. Элемент доxargsпозволяет вставить имя файла, где это необходимо вcatкомандная строка. Скобки заменяются именем файла, передаваемым в Сfind.
использовать ggrep.
ggrep -H -R -I "mysearchstring" *для поиска файла в unix, содержащего текст, расположенный в текущем каталоге или подкаталоге
вы пытаетесь найти текст в файлах? Вы можете просто использовать grep для этого...
grep searchterm *
чтобы перечислить и посмотреть содержимое всех abc.def файлы на сервере в каталогах /ghi и / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;чтобы перечислить abc.def файлы, которые прокомментировали записи и отображения см. Эти записи в каталогах /ghi и /jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
Comments