Wyszukiwanie bez rozróżniania wielkości liter w awk

20

Muszę wyszukać słowo kluczowe za pomocą awk, ale chcę przeprowadzić wyszukiwanie bez rozróżniania wielkości liter (bez rozróżniania wielkości liter).

Myślę, że najlepszym podejściem jest pisanie wielkimi literami zarówno wyszukiwanego terminu („słowo kluczowe”), jak i linii docelowej, którą odczytuje awk w tym samym czasie. Z tego pytania , jak używać toupperdrukowania wielkimi literami, ale nie wiem, jak używać go w dopasowaniu, ponieważ ta odpowiedź pokazuje tylko drukowanie i nie pozostawia tekstu wielkiej litery w zmiennej.

Oto przykład, biorąc pod uwagę następujące dane wejściowe:

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

Chciałbym ten wynik:

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

Oto, co mam, ale nie wiem, jak dodać toupper:

awk "BEGIN {p=0}; /&&&key word&&&/ { p = ! p ; next } ; p { print }" text.txt
Woeitg
źródło

Odpowiedzi:

23

Zamień swoje wyrażenie, aby dopasować wzór (tj. /&&&key word&&&/) Innym wyrażeniem, używając jawnie $0bieżącego wiersza:

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

lub

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

więc masz

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

Potrzebujesz pojedynczych cudzysłowów, ponieważ $0blok BEGIN może zostać usunięty, ponieważ zmienne są domyślnie inicjowane do pierwszego użycia ""lub 0przy pierwszym użyciu i {print}jest to domyślna akcja, jak wspomniano w komentarzach poniżej.

meuh
źródło
4
Pamiętaj, że możesz to uprościć awk 'toupper($0)~/&&&KEY WORD&&&/ { p = ! p ; next } ; p;' text.txt. BEGINBlok nie jest potrzebny, a ponieważ domyślną czynnością jest drukowanie, p;wystarczy.
terdon
1
BEGINBlok nie jest potrzebny ”, ponieważ niezainicjowana zmienna ma wartość false.
glenn jackman
Dzięki za optymalizacje. Zwykle próbuję ograniczyć odpowiedź do minimalnych zmian w oryginale, ale to prawda, że ​​nowy wynik jest znacznie ściślejszy i dość czytelny.
Meuh
2
Tylko uwaga: tolowerjest obecny na starożytnych (lub nie tak starożytnych) wersjach awk (np. AIX), ale touppernie zawsze jest dostępny ^^.
Olivier Dulac
16

gawk ma IGNORECASEwbudowaną zmienną, która, jeśli ustawiona na wartość niezerową, powoduje, że wszystkie porównania ciągów i wyrażeń regularnych nie uwzględniają wielkości liter. Możesz użyć tego:

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

itp. Jest to jednak specyficzne gawk, ale uważam, że jest bardziej czytelne niż (bardziej przenośna) alternatywa autorstwa meuh. To, czy jest to problem, zależy oczywiście od Ciebie.

Wouter Verhelst
źródło
1
Chciałem wspierać awk od lat w jednym z moich największych projektów gawk, ale brak wyszukiwania bez rozróżniania wielkości liter powoduje, że gawk sprawił, że nie zaczął on ze względu na liczbę wyszukiwań bez rozróżniania wielkości liter. gensub to kolejna funkcja gawk, która była zbyt trudna do zastąpienia w awk. Ale gawk nie zawsze jest domyślnie instalowany na niektórych maszynach i dystrybucjach, chociaż prawie zawsze jest dostępny, ale szkoda, że ​​do 2016 r. Nie mogli zmienić awk i posix, aby nieco rozszerzyć funkcjonalność takich standardowych narzędzi.
Lizardx
3
@Lizardx: to jest sedno nierozwijania się: zachowaj standard. W przeciwnym razie po prostu tworzysz kolejny standard, a następnie masz między nimi pewne niekompatybilności (robią to, ale staraj się ograniczyć standardowe zmiany do minimum ... nawet wtedy wiele standardów jest jedną z głównych plag komputerowych)
Olivier Dulac
2
Nie zgadzam się Dzięki starannemu wykonaniu możesz wprowadzać rozszerzenia, jednocześnie obsługując wszystkie starsze metody, co się stanie, jeśli tego nie zrobisz, ponieważ z czasem elementy zaczną znikać. Wszystko w informatyce ewoluuje, sztuką jest utrzymanie bardzo stabilnej i niezawodnej ewolucji. Bash jest dobrym przykładem tego, super niezawodnym i po prostu dodającym nowe funkcje, nie tyle „dwoma standardami”, ile korzystaj z tego, co jest obsługiwane, a po wprowadzeniu zmian na całym świecie możesz zacząć korzystać z nowych funkcji, ponieważ tylko najstarsze starsze systemy nie będą miały wsparcia.
Lizardx