Я делаю, find
а затем получаю список файлов. Как передать это другой утилите cat
( например, чтобы cat отображал содержимое всех этих файлов), и в основном нужно grep
что-то из этих файлов.
Я делаю, find
а затем получаю список файлов. Как передать это другой утилите cat
( например, чтобы cat отображал содержимое всех этих файлов), и в основном нужно grep
что-то из этих файлов.
Ответы:
Трубопровод к другому процессу (хотя это НЕ ПОЛУЧИТ то, что вы сказали, что пытаетесь сделать):
command1 | command2
Это отправит вывод command1 как ввод command2
-exec
на find
(это будет делать то, что вы хотите сделать, - но конкретно find
)
find . -name '*.foo' -exec cat {} \;
(Все, что находится между find
и -exec
являются предикатами поиска, которые вы уже использовали. {}
Будет заменять конкретный файл, который вы нашли в команде ( cat {}
в данном случае); команда \;
должна завершать -exec
команду.)
отправлять вывод одного процесса в качестве аргументов командной строки другому процессу
command2 `command1`
например:
cat `find . -name '*.foo' -print`
(Обратите внимание, что это ЗАДНИЕ ЦИТАТЫ, а не обычные кавычки (под тильдой ~ на моей клавиатуре).) Это отправит вывод command1
в command2
виде аргументов командной строки. Обратите внимание, что имена файлов, содержащие пробелы (новые строки и т. Д.), Будут разбиты на отдельные аргументы.
find
позволяют писать:, find . -name '*.foo' -exec cat {} +
где +
указывает, что find
следует объединить столько имен файлов, сколько это удобно, в один вызов команды. Это очень полезно (оно работает с пробелами и т. Д. В именах файлов, не прибегая к -print0
и xargs -0
).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008 добавил +
маркер, find
который означает, что теперь он автоматически группирует столько файлов, сколько разумно, в одно выполнение команды, очень похоже на то, что xargs
делает, но с рядом преимуществ:
Проблема с именем файла - это проблема xargs
без -0
опции, а проблема «даже с нулевыми именами файлов» - это проблема с или без -0
опции, но GNU xargs
имеет опцию -r
или, --no-run-if-empty
чтобы предотвратить это. Кроме того, эта запись сокращает количество процессов, а не то, что вы, скорее всего, будете измерять разницу в производительности. Следовательно, вы могли бы разумно написать:
find . -exec grep something {} +
find . -print | xargs grep something
Если вы находитесь на Linux или имеют GNU find
и xargs
команды, а затем использовать -print0
с find
и -0
с xargs
к именам файлов ручки , содержащими пробелы и другие символы нечетным мяч.
find . -print0 | xargs -0 grep something
grep
Если вам не нужны имена файлов (только текст), добавьте соответствующую опцию grep
(обычно -h
для подавления «заголовков»). Чтобы гарантировать абсолютную гарантию того, что имя файла напечатано с помощью grep
(даже если найден только один файл или для последнего вызова grep
задано только 1 имя файла), добавьте /dev/null
в xargs
командную строку, чтобы всегда было как минимум два имени файла.
xargs grep something
.
find
передается на стандартный ввод xargs
. xargs
Программа считывает стандартный ввод, разделяя вход в пустое пространство (пробелы, новые строки, вкладки и т.д.) и добавляет число слов в команду grep something
и выполняет командную строку. xargs
затем продолжает чтение ввода и выполнение команд, пока не закончится ввод. xargs
запускает grep
команду так часто, как это необходимо для вводимого ею ввода (из find
этого примера).
/dev/null
теряет сообщения об ошибках.
Есть несколько способов передать список файлов, возвращаемых find
командой cat
команде, хотя технически не все используют конвейерную связь, и ни один из них на самом деле не направляется напрямую cat
.
Самое простое - использовать backticks ( `
):
cat `find [whatever]`
Это берет вывод find
и эффективно помещает его в командную строку cat
. Это не работает, если find
выводится слишком много (больше, чем может поместиться в командной строке) или если вывод содержит специальные символы (например, пробелы).
В некоторых оболочках, в том числе bash
, можно использовать $()
вместо обратных галочек:
cat $(find [whatever])
Это менее переносимо, но является вложенным. Помимо этого, он имеет почти те же предостережения, что и кавычки.
Поскольку выполнение других команд для того, что было найдено, является общеупотребительным find
, find находит -exec
действие, которое выполняет команду для каждого найденного файла:
find [whatever] -exec cat {} \;
{}
Является заполнителем для имени файла, и \;
помечает конец команды (возможно , чтобы другие действия после -exec
.)
Это будет выполнено cat
один раз для каждого отдельного файла, а не для запуска одного экземпляра с cat
передачей ему нескольких имен файлов, что может быть неэффективно и может не соответствовать желаемому поведению некоторых команд (хотя это хорошо для cat
). Синтаксис также неудобен для ввода - вам нужно избегать точки с запятой, потому что точка с запятой является особенной для оболочки!
Некоторые версии find
( в первую очередь в версии GNU) позволяют заменить ;
с +
для использования -exec
« в режиме 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
... +
, хотя и более переносимо (но, к сожалению, более многословно).
ls
.
$()
Также работает с командами, кроме find
.
Похоже, работа для сценария оболочки для меня:
for file in 'find -name *.xml'
do
grep 'hello' file
done
или что-то вроде того
Команда 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
разберусь с этим.
-print0
Аргумент find
сеток с -0
аргументом xargs
для обработки имен файлов с пробелами правильно. -i
Аргумент xargs
позволяет вставить имя файла , где это необходимо в cat
командной строке. Скобки заменяются именем файла, переданным в cat
команду from find
.
Это работает для меня
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Используйте ggrep .
ggrep -H -R -I "mysearchstring" *
искать файл в unix, содержащий текст, расположенный в текущем каталоге или подкаталоге
Это напечатает имя и содержимое файлов только рекурсивно.
find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Редактировать (улучшенная версия): будет рекурсивно печатать имя и содержимое текстовых (ascii) файлов.
find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
Еще одна попытка
find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
Вы пытаетесь найти текст в файлах? Вы можете просто использовать 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 ^# {} \;
find -name '*.foo' -print
отлично сработал для меня ... Спасибо