Поиск без учета регистра в awk

20

Мне нужно найти ключевое слово с помощью awk, но я хочу выполнить поиск без учета регистра (без учета регистра).

Я думаю, что лучший подход состоит в том, чтобы использовать как поисковый термин («ключевое слово»), так и целевую строку, которую awk читает одновременно. Из этого вопроса я toupperузнаю, как использовать для печати все прописные буквы, но я не знаю, как использовать его в совпадении, потому что этот ответ просто показывает печать и не оставляет заглавный текст в переменной.

Вот пример, учитывая этот вход:

blablabla    
&&&Key Word&&&
I want all 
these text and numbers 123
and chars !"£$%&
as output
&&&KEY WORD&&&
blablabla

Я хотел бы этот вывод:

I want all 
these text and numbers 123
and chars !"£$%&
as output

Это то, что у меня есть, но я не знаю, как добавить в toupper:

awk "BEGIN {p=0}; /&&&key word&&&/ { p = ! p ; next } ; p { print }" text.txt
Woeitg
источник

Ответы:

23

Замените ваше выражение, чтобы оно соответствовало шаблону (то есть /&&&key word&&&/) другому выражению, явно использующему $0текущую строку:

tolower($0) ~ /&&&key word&&&/

или

toupper($0) ~ /&&&KEY WORD&&&/

так что у тебя есть

awk 'tolower($0) ~ /&&&key word&&&/ { p = ! p ; next }; p' text.txt

Вам нужны одинарные кавычки, потому что $0блок BEGIN может быть удален, так как переменные инициализируются по умолчанию ""или 0при первом использовании, и {print}это действие по умолчанию, как упомянуто в комментариях ниже.

meuh
источник
4
Обратите внимание, что вы можете упростить это до awk 'toupper($0)~/&&&KEY WORD&&&/ { p = ! p ; next } ; p;' text.txt. Нет необходимости в BEGINблоке, и, поскольку действие по умолчанию - печать, p;достаточно.
Terdon
1
«Нет необходимости в BEGINблоке», поскольку неинициализированная переменная оценивается как ложная.
Гленн Джекман
Спасибо за оптимизацию. Я обычно стараюсь ограничить свой ответ минимальными изменениями оригинала, но это правда, что новый результат гораздо более жесткий и читаемый.
meuh
2
Только примечание: tolowerприсутствует в древних (или не очень древних) системах awk-версий (например, AIX), но toupperне всегда доступно ^^.
Оливье Дюлак
16

У gawk есть IGNORECASEвстроенная переменная, которая, если она не равна нулю, делает все сравнения строк и регулярных выражений нечувствительными к регистру. Вы можете использовать это:

BEGIN{IGNORECASE=1}
/&&&key word&&&/ { foo bar baz }

и т. д. Это характерно для gawk, хотя, но я считаю, что он более читабелен, чем (более переносимая) альтернатива от meuh Разве это проблема, конечно, полностью зависит от вас.

Воутер Верхелст
источник
1
Я хотел поддерживать awk годами в одном из моих крупнейших проектов gawk, но отсутствие поиска без учета регистра приводит к тому, что gawk не запускает его из-за большого количества запросов без учета регистра. gensub - другая особенность gawk, которую было слишком сложно заменить в awk. Но gawk не всегда устанавливается по умолчанию на некоторых машинах и дистрибутивах, хотя он почти всегда доступен, но, к сожалению, к 2016 году они не смогли изменить awk и posix, чтобы немного расширить функциональность таких стандартных инструментов.
Lizardx
3
@Lizardx: в этом и заключается смысл не расширяться: придерживайтесь стандарта. В противном случае вы просто создаете другой стандарт, и между ними возникают некоторые несоответствия (они делают это, но стараются свести стандартные изменения к минимуму ... даже тогда, множественные стандарты - это одно из главных бедствий вычислений)
Оливье Дюлак
2
Я не согласна При аккуратном выполнении вы можете вводить расширения, поддерживая все устаревшие методы, что произойдет, если вы не сделаете этого, - это то, что со временем вещи просто начинают неактуальны. Все в вычислительной технике развивается, главное - поддерживать стабильную и надежную эволюцию. Bash - хороший пример того, как это сделать, сверхнадежность и просто добавление новых функций, это не столько «два стандарта», сколько использование того, что поддерживается, и как только изменения будут внедрены в глобальном масштабе, вы можете начать использовать новые функции, потому что только старые устаревшие системы не будут иметь поддержки.
Lizardx