Как безопасно использовать вывод grep в скрипте?

В сценарии я хочу найти файлы, содержащие некоторый текст. Мне нужно знать файл, в котором находится текст, и полную строку в файле, в которой находится текст. grep – это утилита, которая делает это, но как я могу получить вывод в полезную форму, учитывая, что быть : в именах файлов? Есть ли какой-то --porcelain режим для grep который я могу использовать, вроде как команды git часто имеют?

Пример. У меня есть папка с файлами с именем test-num:1:date:jan-2 которую я хочу пропустить. Файлы содержат FAILURE:<some reason> или SUCCESS:<some reason> (среди прочего). Мне нужен сценарий, который ищет определенные причины и сохраняет имя файла, и причина (вся строка текста в порядке) для последующей обработки. Вывод может быть в любом виде структуры данных, если я могу запустить над ним код.

3 Solutions collect form web for “Как безопасно использовать вывод grep в скрипте?”

Существует не такая вещь, как grep --porcelain , обработка специальных символов в именах файлов всегда была запоздалой мыслью в UNIX. Вы могли бы попробовать что-то вроде этого, по цене эффективности:

 pattern='some pattern' for file in ./*; do grep -- "$pattern" "$file" | while read -r line; do printf 'file: %s, line: %s\n' "$file" "$line" done done 

В последних (-ish) версиях GNU grep есть опция -Z которая делает вывод однозначным, но в основном он предназначен для использования как grep -lZ … | xargs -0 grep -lZ … | xargs -0 . Он по-прежнему работает, если вы перечисляете содержимое строки, нулевой байт заменяет двоеточие, а содержимое линии все еще заканчивается на новой строке¹, но оболочки не подходят для обработки нулевых байтов, поэтому вам будет трудно разобрать этот вывод ,

Одним простым решением (с небольшим снижением производительности) является запуск grep для каждого файла по отдельности.

Другое решение – использовать язык Perl или Python. Perl очень хорош в эмуляции grep; grep REGEX в основном perl -ne '/REGEXP/ and print' .

Но вам может не понадобиться это вообще, если вывод не является фактически двусмысленным. Например, если совпадающие строки не содержат двоеточие, тогда имя файла – это все в строке до последнего двоеточия. Если соответствующие строки начинаются с SUCCESS или FAILURE и эти слова не отображаются в именах файлов, вы можете использовать это, чтобы найти разделение и т. Д.

¹ За исключением случаев использования -z для фильтрации записей с нулевым завершением, а не для записей с завершающим расширением строки, то null – это как ограничитель имени файла, так и терминатор результата; без -o выход по-прежнему однозначен, причем переменные выходные записи являются именами файлов и соответствующими записями на выходе.

Как безопасно использовать вывод grep в скрипте?

… Выход может быть в любом виде структуры данных, пока я могу запускать над ним код.

В сценариях оболочки нет структур данных. Есть массивы, но это все, и нелегко получить безопасный вывод в массив. (Имена файлов могут содержать символы новой строки.)

Лучший способ запустить код над вашими файлами в сценарии оболочки – просто запустить код поверх файлов, а не пытаться сохранить имена файлов для последующего использования.

Для этого используйте find :

 find somedir -type f -exec grep -q somepattern {} \; -exec somecommand {} \; 

Однако, читая ваш вопрос более внимательно, похоже, что вы на самом деле не хотите запускать код поверх своих файлов, вы просто хотите сделать некоторую текстовую обработку на определенных строках. В этом случае опция -z Grep -z – это, вероятно, то, что вы хотите. Это, и знание Sed или Awk, будет решать ваш вопрос.


Возможно, было бы разумно изменить соглашение об именах файлов.

  • Ошибка фиксации сигнала 13 (SIGPIPE) для поиска и grep-конвейера
  • Ошибка команды grep
  • Как grep строка в файле и выводить число рядом со строкой
  • grep-шаблоны из файла1 в столбец file2
  • Как получить несколько строк из файла с помощью регулярных выражений?
  • Как выводить несколько строк с использованием одного условия?
  • Вывод строк поиска с использованием grep в UNIX
  • Объединение двух CSV по сравнению только с определенным столбцом
  • find + grep не работает
  • Как вставить содержимое файла в строку в bash
  • Убедите grep выводить все строки, а не только те, у которых есть совпадения
  • Добавьте возврат каретки к выходу `tail` при использовании` grep`
  • Interesting Posts

    Как мне перейти на новый Firefox через YaST в OpenSuSE 11.x?

    Что делать после паники ядра в AIX?

    Должен ли я включить Intel-микрокод (Linux Mint 18)?

    mv .. с путём: куда идет мой файл?

    Настройте bash, чтобы всегда включать определенный параметр

    Избегание обычного текстового пароля в http_proxy

    корицы: получить оригинальный внешний вид, используя xsession

    Почему большая часть диска io связана с jbd2, а не с процессом, который фактически использует io?

    Как я могу установить или работать с ядром Ubuntu? Есть ли другие ядра?

    Как добавить коммутатор апплета клавиатуры в панель инструментов Fluxbox?

    Как определить оставшееся пространство на изолированном разделе из командной строки

    Как мне получить предварительно обработанную конфигурацию гостя LXC?

    Что означает тире «-» в командной строке Unix?

    IPTables перенаправляет все UDP-пакеты, включая ESTABLISHED

    Звуковой тон / синусоидальный генератор с частотным датчиком

    Linux и Unix - лучшая ОС в мире.