Как выделить совпадающий шаблон регулярного выражения, полученный с помощью многих регексов, разделенных || в awk?

Вопрос или проблема

Эту функцию подсветки можно легко реализовать в grep с помощью --color. Но grep не может выполнять обычное и обратное сопоставление одновременно, например, grep foo -v bar ... (мне нужна эта функция, так как --color можно использовать только в начальном вводе канала |, поэтому последующий grep будет использовать эти цветные результаты, что делает grep foo --color=always ... | grep -v "foo bar" так, чтобы не удалялись эти строки с “foo bar”).

Поэтому я использовал awk, как предлагает вышеуказанная ссылка, но в нем отсутствует функция подсветки. Мы можем извлечь результаты регулярного выражения с помощью match и substr, где мы оборачиваем шаблон регулярного выражения в match как /\<no issue\>/. Затем мы можем подсветить только результат регулярного выражения с помощью кодов цвета ANSI, используя printf substr($0,1,RSTART-1) "\033[1;31m" substr($0,RSTART,RLENGTH) "\033[0m: " substr($0,RSTART+RLENGTH) "\n".

В:

Но match не работает для булевого выражения /foo/ && !/bar/, составленного из reg.exp в ссылке. Есть ли одно элегантное решение (может быть, с другими инструментами)?

Я подумал об одном временном решении /foo/ && !/bar/{match($0,/foo/); printf ...}, но это заставит выполнить регулярное выражение дважды.

Я бы использовал perl здесь. Чтобы подсветить foo в строках, которые не содержат foo bar:

perl -pe 's/foo/\e[31;1m$&\e[m/g unless /foo bar/'

Или чтобы подсветить foo, которые не следуют за bar.

perl -pe 's/foo(?! bar)/\e[31;1m$&\e[m/g'

Ваше временное решение абсолютно приемлемо. Обратите внимание, что, поскольку, видимо, вы используете
GNU awk, вы также можете использовать sub() или
gsub() для замены регулярного выражения строкой, где & заменяется
соответствующей частью:

/foo/ && !/bar/ {
  sub(/foo/, "\033[1;31m" "&" "\033[0m: ")  # изменяет $0
  print
}

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

!/bar/{ if(/foo/){ sub(...); print } }

или, так как sub() возвращает 1 при успешном выполнении

!/bar/{ if(sub(/foo/, ...)) print }

или

!/bar/ && sub(/foo/, ...) { print }

Ответ или решение

Для решения задачи выделения совпадающего шаблона регулярного выражения, используя множество регулярных выражений, объединенных через ‘||’ в awk, необходимо использовать несколько подходов. В grep эта задача решается прямо с помощью ключа --color, однако он не поддерживает одновременно обратное и прямое совпадение. Например, команда grep foo -v bar ... не является допустимой для желаемого эффекта.

Решение задачи с использованием awk

Вы можете использовать awk, но традиционно он не поддерживает выделение текста. Однако, используя ANSI-коды, вы можете реализовать цветовое выделение.

Вот пример использования awk, который позволит вам выделить текст, используя ANSI-коды:

awk '/foo/ && !/bar/ {
    sub(/foo/, "\033[1;31m&\033[0m")
    print
}'

Пояснение:

  1. Условие /foo/ && !/bar/ позволяет находить строки, содержащие foo, но не bar.
  2. sub(/foo/, "\033[1;31m&\033[0m") заменяет найденный текст foo на его красную версию.
  3. print выводит изменённую строку.

Альтернативный подход с использованием Perl

При использовании Perl, задача становится еще более прямолинейной благодаря лаконичности синтаксиса:

perl -pe 's/foo/\e[31;1m$&\e[m/g unless /foo bar/'

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

Зачем использовать Perl:

  • Простота и лаконичность: Perl предлагает более прямолинейный синтаксис для обработки строк.
  • Мощные инструменты для работы с текстом: Perl традиционно используется для текстовой обработки, что делает его более удобным для подобных задач.

SEO-оптимизация и профессиональный подход

Ваша стратегия использования регулярных выражений влияет на производительность скрипта. Применение различных инструментов, таких как awk и Perl, должно основываться на конкретных требованиях задачи и внутренних процессах команды.

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

Если у вас есть дополнительно вопросы по оптимизации подобных скриптов или другим вопросам работы с текстовыми потоками в Unix-системах, не стесняйтесь обращаться за профессиональной консультацией.

Оцените материал
Добавить комментарий

Капча загружается...