Как передать список файлов, возвращенных командой find в cat для просмотра всех файлов
Я делаю find
а затем получение списка файлов. Как я могу передать его другой утилите, такой как cat
(Так что cat отображает содержимое всех этих файлов) и в основном нужно grep
что-то из этих файлов.
14 ответов
-
трубопровод к другому процессу (хотя это не будет выполнять то, что вы сказали, что пытаетесь сделать):
command1 | command2
это отправит вывод command1 в качестве ввода command2
-
-exec
наfind
(этот будет делать то, что вы хотите сделать, но относящиеся кfind
)find . -name '*.foo' -exec cat {} \;
(между
find
и-exec
являются предикатами find, которые вы уже использовали.{}
заменить конкретный файл, который вы нашли в команде (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
.
-
самое простое - использовать backticks (
`
):cat `find [whatever]`
это принимает выход
find
и эффективно помещает его в командную строкуcat
. Это не работает хорошо, еслиfind
слишком много выходных (больше, чем может поместиться в командной строке) или если выходные данные имеют специальные символы (например, пробелы). -
в некоторых оболочках, в том числе
bash
можно использовать$()
вместо backticks:cat $(find [whatever])
это менее портативный, но nestable. Помимо этого, у него есть почти те же предостережения, что и backticks.
-
потому что выполнение других команд на том, что было найдено, является общим использованием для
find
, имеет-exec
действие, которое выполняет команду для каждого файла находит:find [whatever] -exec cat {} \;
на
{}
является заполнителем для имени файла и\;
отмечает конец команды (после-exec
.)это будет работать
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 cat
на
-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
разберется, что все это для вас.
на до find
сетки с до xargs
для правильной обработки имен файлов с пробелами. The до 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 ^# {} \;