Я делаю find
, а затем получаю список файлов. Как я могу подключить его к другой утилите, например cat
(так что кошка отображает содержимое всех этих файлов) и в основном нужно grep
что-то из этих файлов.Как передать список файлов, возвращаемых командой find, чтобы просмотреть все файлы
ответ
трубопровода к другому процессу (хотя это не будет выполнять то, что вы сказали, что вы пытаетесь сделать):
command1 | command2
Это направит выход command1 как вход команды команда2
-exec
наfind
(это будет делать то, что вы хотели сделать - но только дляfind
)find . -name '*.foo' -exec cat {} \;
(Все между
find
и-exec
- это предикаты поиска, которые вы уже использовали.{}
заменит конкретный файл, который вы нашли в команде (cat {}
в этом случае);\;
является для завершения команды-exec
)отправить выход одного процесса в качестве аргументов командной строки к другому процессу
command2 `command1`
, например:.
cat `find . -name '*.foo' -print`
(Примечание эти обратно- QUOTES не регулярные кавычки (под тильдой ~ на моей клавиатуре).) Это приведет к выходу
command1
вcommand2
в качестве аргументов командной строки. Обратите внимание, что имена файлов, содержащие пробелы (новые строки и т. Д.), Будут разбиты на отдельные аргументы.
Похоже, работа для сценария оболочки для меня:
for file in 'find -name *.xml'
do
grep 'hello' file
done
или что-то подобное
Это действительный, хотя и не обязательно оптимальный ответ на вопрос. –
... да, но это здорово, если вам нужен один большой файл с именами, перечисленными также. –
Мне нравится это лучшее. Такой блок петли оставляет место, чтобы делать другие вещи. – kakyo
find . -print | xargs grep something
Если вы находитесь на Linux или имеют GNU find
и xargs
, а затем использовать -print0
с find
и -0
с xargs
для обработки имен файлов, содержащих пробелы и другие символы нечетного шара.
Если вы не хотите, чтобы имена файлов - только текст - добавьте соответствующую опцию в grep
(обычно -h
для подавления «заголовков»). Чтобы абсолютно гарантировать, что имя файла напечатано grep
(даже если найден только один файл или последнему вызову grep
присваивается только одно имя файла), затем добавьте /dev/null
в командную строку xargs
, чтобы всегда было по крайней мере два имени файла.
Обратите внимание, что POSIX 2008 добавило +
маркера find
, который означает, что он теперь автоматически группы, как много файлов, которые являются разумными в одном исполнение команды, очень похож xargs
делает, но с целым рядом преимуществ:
- Вам не нужно беспокоиться о нечетных символах в именах файлов.
- Вам не нужно беспокоиться о вызове команды с нулевыми именами файлов.
Оба эти вопроса являются с xargs
без опции -0
. Таким образом, вы могли бы толково написать:
find . -exec grep something {} +
Для тех, кто смущен, как и я, обратите внимание, что этот путь сначала даст весь вывод find, а затем даст результат 'xargs grep something'. –
@EricHu: Я вижу, что вы в замешательстве, но он не делает то, что вы говорите, по крайней мере, не на какой-либо системе на основе Unix, о которой я знаю. Выход 'find' отправляется на стандартный вход' xargs'. Программа «xargs» считывает свой стандартный ввод, разделяя входные данные на пробел (пробелы, символы новой строки, вкладки и т. Д.) И добавляет несколько слов в команду 'grep something' и выполняет командную строку. 'xargs' затем продолжает чтение ввода и выполнение команд, пока не закончится вход. 'xargs' запускает команду' grep' столько раз, сколько необходимо для введенного им ввода (из 'find' в этом примере). –
Ах, моя ошибка, это использование grep для поиска в каждом файле.Я хотел просто фильтровать вывод find с grep –
Команда находка имеет -exec аргумент, который вы можете использовать для таких вещей, как это, вы могли бы просто сделать Grep непосредственно с помощью этого.
Например (from here, other good examples at this page):
find . -exec grep "www.athabasca" '{}' \; -print
Вы пытаетесь найти текст в файлах? Вы можете просто использовать Grep для этого ...
grep searchterm *
Есть несколько способов, чтобы пройти список файлов, возвращаемых командой find
к команде cat
, хотя технически не все использования трубопроводов, и никто на самом деле трубы непосредственно до cat
.
Проще всего использовать кавычку:
cat `find [whatever]`
Эквивалентно, можно использовать
$()
вместо обратные кавычки в некоторых оболочках, в том числеbash
:cat $(find [whatever])
Это менее переносимым, но является гнездовым.
Оба синтаксиса берут вывод
find
и помещают его в командную строкуcat
. Это не очень хорошо работает, еслиfind
имеет слишком большой вывод (больше, чем может поместиться в командной строке), или если на выходе есть специальные символы (например, пробелы).Вы можете использовать
-exec
действиеfind
«s, который выполняет команды для каждого файла, он находит:find [whatever] -exec cat {} \;
Это будет работать
cat
один раз для каждого файла, а не работает один экземплярcat
передачи его несколько имен файлов, которые могут быть неэффективными и могут не иметь поведения, которое вы хотите для некоторых команд (хотя это нормально дляcat
). Синтаксис также неудобен для ввода - вам нужно избежать точки с запятой, поскольку точка с запятой является специальной для оболочки!Некоторых версии
find
(в первую очередь в версии GNU) позволяют заменить;
с+
использоватьfind
«s режим приобщать для запуска меньше экземпляровcat
.find [whatever] -exec cat {} +
Это будет пройти несколько имен файлов для каждого вызова
cat
, который может быть более эффективным. Обратите внимание, что это не гарантированно использует один вызов. Если командная строка слишком длинная, аргументы распределяются между несколькими вызовамиcat
. Дляcat
это, вероятно, не имеет большого значения, но для некоторых других команд это может изменить поведение нежелательными способами. В системах Linux ограничение длины командной строки довольно велико, поэтому разбиение на несколько вызовов довольно редко по сравнению с некоторыми другими операционными системами.Классический/портативный подход заключается в использовании
xargs
:find [whatever] | xargs cat
xargs
запускает команду, указанную (cat
, в данном случае), и добавляет аргументы, основанные на том, что он читает из стандартного ввода. Точно так же, как-exec
с+
, при необходимости он распадет командную строку. То есть, еслиfind
производит слишком большой объем вывода, он будет запускатьcat
несколько раз. Как упоминалось ранее в разделе о-exec
, есть некоторые команды, в которых это расщепление может привести к поведению. Обратите внимание, что использованиеxargs
, как это имеет место с пробелами в именах файлов, так какxargs
просто использует пробелы в качестве разделителя.Самый надежный, портативный и эффективный метод также использует
xargs
:find [whatever] -print0 | xargs -0 cat
Флаг
-print0
говоритfind
использовать\0
(нулевой символ) разделители между именами файлов и-0
флаг говоритxargs
ожидать, что эти\0
разделители. Это очень похоже на подход-exec
...+
, хотя и более портативный (но, к сожалению, более подробный).
Чтобы получить список и увидеть содержимое всех abc.def файлов на сервере в каталогах/ГХИ и/JKL
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;
Чтобы перечислить abc.def файлы, которые комментировали записи и отображать см эти записи в каталогах/ГХИ и/JKL
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
В Баш, то было бы целесообразно следующее:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
Здесь вы найдете все файлы в каталоге /dir
и безопасно проложите имена файлов в xargs
, которые безопасно будут управлять grep
.
Пропуск xargs
не рекомендуется, если у вас много тысяч файлов в /dir
; cat
сломается из-за чрезмерной длины списка аргументов. xargs
сортирует все для вас.
-print0
аргумент find
зацепляется с -0
аргументом xargs
обрабатывать имена файлов с пробелами правильно. Аргумент -i
до xargs
позволяет вставить имя файла, если требуется в командной строке cat
. Скобки заменяются на имя файла, поданного в команду cat
от find
.
Вот мой выстрел для общего использования:
grep YOURSTRING `find .`
Он будет печатать имя файла
Это работает для меня
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Для достижения этого (с помощью Баша) Я хотел бы сделать следующим образом:
cat $(find . -name '*.foo')
Это называется «подстановкой команд», и по умолчанию он лимитирует фид линии, что действительно удобно! больше
информация о here
Используйте ggrep.
ggrep -H -R -I "mysearchstring" *
для поиска файла в UNIX, содержащий текст, расположенный в текущем каталоге или подкаталоге
Вот мой способ найти имена файлов, которые содержат некоторое содержание, что я заинтересован в, только один баш линия, которая хорошо обрабатывает пробелы в именах файлов тоже:
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>
«аргумент« find »и« -0
»аргумент« xargs »необходим для правильной обработки пробелов в путях/именах файлов.
cat 'find -name '* .foo' -print' отлично подойдет для меня ... Спасибо –
Backquotes отлично работают и более обобщен, вы можете использовать это, чтобы cat список файлов из файла. – Hazok
Обратите внимание, что современные версии 'find' позволяют вам писать:' find. -name '* .foo' -exec cat {} + ', где' + 'указывает, что' find' должен группировать как можно больше имен файлов в один командный вызов. Это очень полезно (он имеет дело с пробелами и т. Д. В именах файлов, не прибегая к '-print0' и' xargs -0'). –