Как передать список файлов, возвращаемых командой find, чтобы просмотреть все файлы

Я делаю find, а затем получаю список файлов. Как мне передать его на другую утилиту, например, cat (так что cat отображает содержимое всех этих файлов) и в основном нужно grep что-то из этих файлов.

Ответы

Ответ 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, но с рядом преимуществ:

  1. Вам не нужно беспокоиться о нечетных символах в именах файлов.
  2. Вам не нужно беспокоиться о том, что команда вызывается с нулевыми именами файлов.

Обе эти проблемы 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.

  1. Самое простое - это использовать обратные галочки ('):

    cat 'find [whatever]'
    

    Это берет вывод find и эффективно помещает его в командную строку cat. Это не работает, если find имеет слишком много выходных данных (больше, чем может поместиться в командной строке) или если выходные данные содержат специальные символы (например, пробелы).

  2. В некоторых оболочках, включая bash, можно использовать $() вместо обратных галочек:

    cat $(find [whatever])
    

    Это менее переносимо, но является вложенным. Помимо этого, он имеет почти те же предостережения, что и кавычки.

  3. Поскольку выполнение других команд для найденного является обычным использованием find, find имеет действие -exec которое выполняет команду для каждого -exec файла:

    find [whatever] -exec cat {} \;
    

    {} Является заполнителем для имени файла, а \; отмечает конец команды (возможны другие действия после -exec.)

    Это будет запускать cat один раз для каждого отдельного файла, а не запускать один экземпляр cat передавая ему несколько имен файлов, что может быть неэффективно и может не соответствовать желаемому поведению некоторых команд (хотя это хорошо для cat). Синтаксис также неудобен для ввода - вам нужно избегать точки с запятой, потому что точка с запятой является особенной для оболочки!

  4. Некоторые версии find (особенно версия GNU) позволяют вам заменить ; + использовать -exec добавления -exec для запуска меньшего количества экземпляров cat:

    find [whatever] -exec cat {} +
    

    Это передаст несколько имен файлов каждому вызову cat, что может быть более эффективным.

    Обратите внимание, что это не гарантирует использовать один вызов, однако. Если командная строка будет слишком длинной, то аргументы будут распределены по нескольким вызовам cat. Для cat это, вероятно, не имеет большого значения, но для некоторых других команд это может изменить поведение нежелательным образом. В системах Linux ограничение длины командной строки довольно велико, поэтому разбиение на несколько вызовов довольно редко по сравнению с некоторыми другими операционными системами.

  5. Классический/переносимый подход заключается в использовании xargs:

    find [whatever] | xargs cat
    

    xargs запускает указанную команду (в данном случае cat) и добавляет аргументы на основе того, что она читает из stdin. Точно так же, как -exec с +, это сломает командную строку при необходимости. То есть, если find выдает слишком много информации, она будет запускать cat несколько раз. Как упоминалось в разделе о -exec ранее, есть некоторые команды, в которых это разделение может привести к другому поведению. Обратите внимание, что при использовании xargs подобных этому, xargs проблемы с пробелами в именах файлов, поскольку xargs просто использует пробел в качестве разделителя.

  6. Самый надежный, переносимый и эффективный метод также использует 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" необходим для правильной обработки пробелов в путях/именах файлов.

Ответ 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 ^# {} \;