Я делаю find
, а затем получаю список файлов. Как мне передать его на другую утилиту, например, cat
(так что cat отображает содержимое всех этих файлов) и в основном нужно grep
что-то из этих файлов.
Как передать список файлов, возвращаемых командой find, чтобы просмотреть все файлы
Ответ 1
-
Трубопровод к другому процессу (хотя это НЕ будет выполнено, что вы сказали, что вы пытаетесь сделать):
command1 | command2
Это отправит вывод команды 1 в качестве ввода команды2
-
-exec
наfind
(это будет делать то, что вы хотите сделать, но имеет значение дляfind
)find . -name '*.foo' -exec cat {} \;
(Все между
find
и-exec
- это предикаты поиска, которые вы уже использовали.{}
заменит конкретный файл, который вы нашли в команде (cat {}
в этом случае);\;
- завершите команду-exec
.) -
отправить вывод одного процесса в качестве аргументов командной строки в другой процесс
command2 `command1`
например:
cat `find . -name '*.foo' -print`
(Обратите внимание: это BACK-QUOTES не обычные кавычки (под тильдой ~ на моей клавиатуре).) Это отправит вывод
command1
вcommand2
в качестве аргументов командной строки. Обратите внимание, что имена файлов, содержащие пробелы (новые строки и т.д.), Будут разбиты на отдельные аргументы.
Ответ 2
Современная версия
POSIX 2008 добавил маркер +
чтобы find
что означает, что теперь он автоматически группирует столько файлов, сколько разумно, в одно выполнение команды, очень похоже на xargs
, но с рядом преимуществ:
- Вам не нужно беспокоиться о нечетных символах в именах файлов.
- Вам не нужно беспокоиться о том, что команда вызывается с нулевыми именами файлов.
Обе эти проблемы xargs
с xargs
без опции -0
(а запуск даже с 0 именами файлов - это проблема с опцией -0
или без -0
). Кроме того, эта запись сокращает количество процессов, а не то, что вы, скорее всего, будете измерять разницу в производительности. Следовательно, вы могли бы разумно написать:
find . -exec grep something {} +
Классическая версия
find . -print | xargs grep something
Если вы работаете в Linux или используете команды GNU find
и xargs
, то используйте -print0
с find
и -0
с xargs
для обработки имен файлов, содержащих пробелы и другие нечетные символы.
find . -print0 | xargs -0 grep something
Если вам не нужны имена файлов (только текст), добавьте соответствующую опцию в grep
(обычно -h
для подавления "заголовков"). Чтобы абсолютно гарантировать, что имя файла напечатано с помощью grep
(даже если найден только один файл или при последнем вызове grep
задано только 1 имя файла), добавьте /dev/null
в командную строку xargs
, чтобы всегда было быть как минимум два имени файла.
Ответ 3
Есть несколько способов передать список файлов, возвращаемых командой find
команде cat
, хотя технически не все используют конвейерную связь, и на самом деле ни один из них не направляет напрямую в cat
.
-
Самое простое - это использовать обратные галочки (
'
):cat 'find [whatever]'
Это берет вывод
find
и эффективно помещает его в командную строкуcat
. Это не работает, еслиfind
имеет слишком много выходных данных (больше, чем может поместиться в командной строке) или если выходные данные содержат специальные символы (например, пробелы). -
В некоторых оболочках, включая
bash
, можно использовать$()
вместо обратных галочек:cat $(find [whatever])
Это менее переносимо, но является вложенным. Помимо этого, он имеет почти те же предостережения, что и кавычки.
-
Поскольку выполнение других команд для найденного является обычным использованием
find
, find имеет действие-exec
которое выполняет команду для каждого-exec
файла:find [whatever] -exec cat {} \;
{}
Является заполнителем для имени файла, а\;
отмечает конец команды (возможны другие действия после-exec
.)Это будет запускать
cat
один раз для каждого отдельного файла, а не запускать один экземплярcat
передавая ему несколько имен файлов, что может быть неэффективно и может не соответствовать желаемому поведению некоторых команд (хотя это хорошо дляcat
). Синтаксис также неудобен для ввода - вам нужно избегать точки с запятой, потому что точка с запятой является особенной для оболочки! -
Некоторые версии
find
(особенно версия GNU) позволяют вам заменить;
+
использовать-exec
добавления-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
просто использует пробел в качестве разделителя. -
Самый надежный, переносимый и эффективный метод также использует
xargs
:find [whatever] -print0 | xargs -0 cat
Флаг
-print0
указывает, чтоfind
использует разделители\0
(нулевой символ) между именами файлов, а флаг-0
сообщаетxargs
следует ожидать этих разделителей\0
. Это поведение в значительной степени идентично поведению-exec
...+
, хотя и более переносимо (но, к сожалению, более многословно).
Ответ 4
Чтобы достичь этого (используя bash), я бы сделал следующее:
cat $(find . -name '*.foo')
Это называется "подстановкой команд", и по умолчанию он лимитирует фид строки, который действительно удобен!
больше информации здесь
Ответ 5
Мне нравится работа для оболочки script для меня:
for file in 'find -name *.xml'
do
grep 'hello' file
done
или что-то в этом роде
Ответ 6
Здесь мой способ найти имена файлов, которые содержат некоторый контент, который мне интересен, только одна строка bash, которая прекрасно обрабатывает пробелы в именах файлов:
find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done
Ответ 7
Я использую что-то вроде этого:
find . -name <filename> -print0 | xargs -0 cat | grep <word2search4>
"-print0
" аргумент для аргумента "find" и "-0
" для "xargs" необходим для правильной обработки пробелов в путях/именах файлов.
Ответ 8
В команде find есть аргумент -exec, который вы можете использовать для таких вещей, вы можете просто использовать grep напрямую, используя это.
Например (отсюда, другие хорошие примеры на этой странице):
find . -exec grep "www.athabasca" '{}' \; -print
Ответ 9
В bash было бы уместно следующее:
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
.
Ответ 10
Вот мой снимок для общего использования:
grep YOURSTRING `find .`
Он выведет имя файла
Ответ 11
Это работает для меня
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Ответ 12
Используйте ggrep.
ggrep -H -R -I "mysearchstring" *
для поиска файла в unix, содержащего текст, расположенный в текущем каталоге или подкаталоге
Ответ 13
Вы пытаетесь найти текст в файлах? Вы можете просто использовать grep для этого...
grep searchterm *
Ответ 14
Чтобы просмотреть и просмотреть содержимое всех файлов 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 ^# {} \;