Нечутливий до випадків пошук


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

Відповіді:


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}це дія за замовчуванням, як зазначено в коментарях нижче.


4
Зауважте, що ви можете це спростити awk 'toupper($0)~/&&&KEY WORD&&&/ { p = ! p ; next } ; p;' text.txt. У BEGINблоці немає необхідності, і оскільки дія за замовчуванням - це друк, p;достатньо.
terdon

1
"Немає необхідності в BEGINблоці", оскільки неініціалізована змінна оцінюється як хибна.
glenn jackman

Дякуємо за оптимізацію. Зазвичай я намагаюся обмежити свою відповідь мінімальними змінами оригіналу, але це правда, що новий результат набагато чіткіший і читабельний.
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, щоб трохи розширити функціональність таких стандартних інструментів.
Лізардкс

3
@Lizardx: у цьому вся суть не розширення: тримайте його стандартним. Інакше ви просто створите інший стандарт, і тоді у вас є деякі нездатності між ними (вони роблять це, але намагаєтеся звести стандартні зміни до мінімуму ... навіть тоді, кілька стандартних є однією з головних чум обчислень)
Олів'є Дулак

2
Я не згоден. При ретельному виконанні ви можете ввести розширення, підтримуючи всі застарілі методи. Що станеться, якщо ви цього не зробите, то те, що з часом починає відшаровуватися на неактуальність. Все в обчислювальному процесі розвивається, хитрість полягає в підтримці дуже стабільної надійної еволюції. Bash - хороший приклад цього робити, супер надійний і просто додавати нові функції, це не «два стандарти» настільки, що, використовуйте те, що підтримується, і як тільки зміни відбудуться глобально, ви можете почати використовувати нові функції, тому що лише найстаріші застарілі системи не матимуть підтримки.
Ящірка
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.