Вопрос или проблема
Awk бесценен для многих задач, где логика фильтрации текста охватывает несколько строк и необходимо поддерживать состояние (в отличие от grep и sed), но как я недавно обнаружил, могут быть случаи, когда требуется что-то более гибкое (в ущерб простоте).
Что будет следующим на шкале сложности, используя набор инструментов Unix “делай одно дело хорошо”?
cat in.txt | grep foo | tee out.txt
cat in.txt | grep -e foo -e bar | tee out.txt
cat in.txt | sed 's/(foo|bar)/corrected/' | tee out.txt
cat in.txt | awk 'BEGIN{ myvar=0 } /foo/{ myvar += 1} END{ print myvar}' | tee out.txt
cat in.txt | ???? | tee out.txt
Какой будет следующий “классический” подход/инструмент Unix, отвечающий за следующий этап развития сложности?
- Будет ли это самодельный компилятор, использующий
readline
bash? - Хотя Perl может это сделать, я прочитал где-то, что это отступление от философии Unix, заключающейся в “делай одно дело хорошо”.
- Я слышал о
lex
/yacc
,flex
/bison
, но не использовал их. Они кажутся значительным шагом вперед.
Вот мое мнение по этому вопросу:
lex
/yacc
, flex
/bison
в основном являются лексическими анализаторами/синтаксическими анализаторами и ожидают на вход текст на определенном языке. И выдают на выход C
, Java
, C++
и так далее. Поэтому для меня они не совсем то, что вы ищете.
awk
действительно очень мощный язык. Позвольте мне продемонстрировать это на основе ваших примеров:
grep foo in.txt = awk '/foo/' in.txt
grep -e foo -e bar in.txt = awk '/foo|bar/' in.txt
sed 's/(foo|bar)/corrected/' in.txt = awk '{gsub(/foo|bar/,"corrected");}1' in.txt
Таким образом, вы можете использовать его практически везде. Но вы должны хорошо его изучить. Да, иногда конструкции не очень читаемые, но со временем все будет нормально 🙂
Если вы хотите что-то очень мощное, вы можете начать изучать python
. Это можно назвать следующим пунктом в списке. Но python
может быть довольно сложным и (для меня тоже довольно) нечитаемым.
По поводу вашего использования cat
пожалуйста, прочитайте этот вопрос/ответ. Также посмотрите это обсуждение.
После получения большего понимания flex/bison, я хотел бы добавить свой ответ:
grep
– работает с строками, включает/исключаетsed
– работает с символами, выполняет заменуawk
– работает с полями/ячейками, выполняет условную логикуlex-yacc
/flex-bison
– работает с представлением в памяти, созданным из токенизации блоков текста, выполняет преобразование данных
Я уверен, что этому есть контраргументы, но это повествование о континууме, которое устанавливает определенные отношения между классическими инструментами Unix, которые я лично нахожу полезными. Принимайте это или оставьте 🙂
Ответ или решение
Когда awk становится слишком громоздким для обработки текстовых данных, следующая "классическая" подходящая утилита Unix для обработки и трансформации текста может зависеть от специфических задач и требований. В этой ситуации использование более мощных инструментов становится обоснованным. Перейдем к анализу возможных инструментов и концепций, учитывая философию Unix "делай одну вещь и делай ее хорошо".
Теория
Утилита awk часто используется для сложных текстовых фильтраций и поддержания состояния между строками. Однако, когда возникает потребность в более сложной обработке или интеграции данных — таких как манипуляции с большими объемами текста, сложные вычисления и трансформации — потребность в более выраженном программном обеспечении становится очевидной.
Unix философия подразумевает использование различных инструментов, каждый из которых предназначен для специфической задачи, но вместе они способны решать сложные задачи. Некоторые из стандартных утилит:
- grep: обрабатывает строки и предназначен для фильтрации и поиска.
- sed: работает на уровне символов, осуществляет замены и легкие редакции текста.
- awk: ориентирован на обработку полей и выполнение условной логики.
Когда данные инструменты покажут свою ограниченность, следует рассмотреть варианты более мощных языков, таких как Python или Perl, а также утилит как flex/bison для специфических нужд.
Примеры
-
Perl: Позволяет более гибкую обработку текста, чем awk, включая встроенные регулярные выражения, манипуляции с файлами и поддержку сложных данных. Perl не так строго следует философии Unix в плане "делай одну вещь", но может быть полезен в обработке больших объемов текстовых данных.
-
Python: Универсальный язык с богатой библиотекой для работы с текстом, как например
re
для регулярных выражений илиpandas
для структурированной обработки данных. Python предоставляет более интуитивное и понятное решение для сложных задач, а также легко интегрируется с другими системами и инструментами. -
Lex/Yacc или Flex/Bison: Преимущественно для создания компиляторов или парсеров, полезны в случаях, когда необходимо создать специфический языковой процессор или необходимо обработать сложный синтаксис. Они выполняют разбиение на токены и синтаксический анализ, создавая дерево разбора, но требуют предварительных знаний в создании парсеров.
Применение
Когда задачи awk требуют превышающих его возможностей:
- Оцените сложность задачи: выясните, требуется ли действительно сложное преобразование данных или достаточно расширенных регулярных выражений.
- Если задача требует обработки больших объемов данных, использования сложных регулярных выражений или манипуляций с несколькими файлами — рассмотрите использование Python с его мощными инструментами и библиотеками.
- Perl может быть выбран при сильной зависимости от текстовых манипуляций и когда требуется поддержка сложных регулярных выражений не жертвуя производительностью.
- Если задача включает в себя составление парсеров для сложных языков или протоколов, то может быть целесообразно изучение Flex/Bison.
Как видно, переход от awk к более мощным инструментам и утилитам Unix должен быть осведомленным решением, основанным на конкретных потребностях задачи.
Заключение
Переход от awk к следующим инструментам в континууме сложности предполагает важный выбор в использовании технологий для достижения максимальной эффективности и решения сложных задач. Важно помнить, что каждый инструмент имеет свои сильные и слабые стороны и выбирается в зависимости от специфики задач, которые предстоит решить. Использование Python или Perl, а также разработка с помощью Lex/Yacc и Flex/Bison, открывает новые горизонты в обработке данных, поддерживая надежность и гибкость работы в Unix системах.
Используя описанные выше подходы, можно более эффективно решать задачи, которые выходят за рамки возможностей awk, сохраняя приверженность философии Unix и обеспечивая точность и надежность результатов.