Лучший подход для извлечения содержимого совпадающих групп с использованием регулярного выражения в стиле Perl в сценарии оболочки - PullRequest
3 голосов
/ 17 декабря 2011

Моя задача - извлечь некоторые данные из заданного документа с помощью регулярного выражения в стиле Perl (или, по крайней мере, расширенного). У меня есть:

  • исходный документ (как файл, как переменная - это не имеет значения):
    • например: Some text: 1234.55 value more text - 8863 value
  • регулярное выражение в стиле Perl в виде строки
    • например: ^.*: ([0-9.]+) value .* - (\d+) value$

Каков лучший подход для извлечения данных в сценарии оболочки UNIX?

Позвольте мне определить, что я хотел бы видеть в лучший подход , в порядке важности:

  • Переносимость - в идеале, он должен работать в большинстве современных операционных систем и сред - то есть, по крайней мере, GNU / Linux, FreeBSD / OpenBSD, Mac OS X; Cygwin, вероятно, такой же, как Linux, но не во всех случаях
  • Минимальные системные требования - то есть просьба запустить несколько экзотических интерпретаторов / программ, как правило, плохая вещь
  • Добросовестное использование ресурсов - то есть не нужно много времени, чтобы обработать простое регулярное выражение
  • Чистый, маленький, легкий для понимания код

Я понимаю, что невозможно достичь всех этих целей одновременно, поэтому я рассмотрел свои альтернативы:

  • Использование sed - возможно, это был бы лучший способ, но, увы, POSIX sed поддерживает только базовые регулярные выражения, не расширенные и определенно не в стиле perl. Различные реализации добавляют расширения, но они обычно несовместимы: GNU sed использует опцию -r или --regexp-extended для переключения в расширенном режиме и BSD sed (также в Mac OS X ) использует -E.
  • Преобразование расширенных регулярных выражений в базовые и использование оригинальных sed - мне кажется несколько неловким, и я не могу найти ни одного достойного алгоритма, который доказал бы свою эффективность для этой задачи.
  • Использование awk - в общем, то же самое, что и sed, но еще хуже: существует множество реализаций awk с небольшой несовместимостью, а поддержка расширенных регулярных выражений еще более неясна.
  • Использование perl - вероятно, самая простая и разумная альтернатива, но, увы, Perl не везде доступен, как стандартные утилиты POSIX - т.е., насколько я помню, Perl отсутствует в базовой системе * BSD (и Mac). OS X), он требует отдельной установки в мире Cygwin, даже некоторые дистрибутивы Linux дают возможность его опустить.
  • Использование php, python, ruby - такая же ситуация, как с perl, но, как правило, они даже более необычны, как я вижу в современном мире.
  • Использование grep - так же, как с sed; BSD использует GNU grep, но не поддерживает -P AKA --perl-regexp, только -E AKA --extended-regexp в системах BSD. Что еще хуже - кажется невозможным распечатать групп , а не весь сопоставленный шаблон - т.е. использование grep -o (показать только совпадающую часть совпадающей строки) дает только весь шаблон, а не отчетливый значения групп.

Итак, я потерял то, что было бы самым переносимым и простым в поддержке способом. Сейчас я выбираю между:

  • Создайте оболочку над sed, чтобы проверить, используем ли мы BSD или GNU sed, и выполнить соответствующие команды
  • Настаивайте на том, чтобы Perl был установлен, чтобы иметь возможность запускать мой скрипт

Чего-то не хватает в этом обзоре? Каковы были бы лучшие альтернативы? Может быть, где-то уже написана оболочка для этой задачи (т.е. autotools / некоторые другие загадочные проекты, использующие сценарий оболочки)?

1 Ответ

3 голосов
/ 17 декабря 2011

абсолютно портативно сложно.как насчет этого, я не знаю, хорошая ли это идея ...

на самом деле извлечь часть легко, независимо от того, какой инструмент мы используем.интересно решить, если этот инструмент доступен / подходит для текущей системы.

вы можете создать список (массив) всех инструментов, а затем в начале своего скрипта вы можете проверить доступность этих инструментов.Подробные версии, я думаю, что проверки этих простых grep достаточно.например, используя $?для проверки доступности

java -version
//check $? 

python -V
//check $?

с помощью простого grep для проверки деталей версии: например,

awk -V|grep GNU
sed --version|grep GNU
....

, как только вы нашли инструмент, который может выполнять вашу работу, с помощью этого инструмента.Вызов определенного сценария.

однако вам необходимо подготовить N решений для одного и того же вопроса, используя N инструментов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...