Recherche insensible à la casse dans awk

20

J'ai besoin de rechercher un mot clé en utilisant awk, mais je veux effectuer une recherche insensible à la casse (non sensible à la casse).

Je pense que la meilleure approche consiste à capitaliser à la fois le terme de recherche («mot clé») et la ligne cible que awk lit en même temps. À partir de cette question, comment utiliser toupperpour imprimer en majuscules, mais je ne sais pas comment l'utiliser dans une correspondance car cette réponse montre simplement l'impression et ne laisse pas le texte en majuscule dans une variable.

Voici un exemple, compte tenu de cette entrée:

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

J'aimerais cette sortie:

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

C'est ce que j'ai, mais je ne sais pas comment ajouter toupper:

awk "BEGIN {p=0}; /&&&key word&&&/ { p = ! p ; next } ; p { print }" text.txt
Woeitg
la source

Réponses:

23

Remplacez votre expression pour faire correspondre un motif (c.-à-d. /&&&key word&&&/) Par une autre expression utilisant explicitement $0, la ligne actuelle:

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

ou

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

vous avez donc

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

Vous avez besoin de guillemets simples à cause de la $0, le bloc BEGIN peut être supprimé car les variables sont initialisées par défaut à ""ou 0lors de la première utilisation, et {print}c'est l'action par défaut, comme mentionné dans les commentaires ci-dessous.

meuh
la source
4
Notez que vous pouvez simplifier cela awk 'toupper($0)~/&&&KEY WORD&&&/ { p = ! p ; next } ; p;' text.txt. Il n'y a pas besoin de BEGINbloquer et puisque l'action par défaut est d'imprimer, p;c'est suffisant.
terdon
1
"Il n'y a pas besoin du BEGINbloc" car une variable non initialisée est évaluée comme fausse.
glenn jackman
Merci pour les optimisations. J'essaie généralement de limiter ma réponse à des modifications minimes de l'original, mais il est vrai que le nouveau résultat est beaucoup plus serré et assez lisible.
meuh
2
Juste une note: tolowerest présent sur les systèmes awk anciens (ou pas si anciens) (ex: AIX), mais touppern'est pas toujours disponible ^^.
Olivier Dulac
16

gawk a une IGNORECASEvariable intégrée qui, si elle est définie sur non nul, rend toutes les comparaisons de chaînes et d'expressions régulières insensibles à la casse. Vous pouvez utiliser cela:

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

etc. Ceci est spécifique à gawk, cependant, mais je le trouve plus lisible que l'alternative (plus portable) de meuh. Que ce soit un problème, cela dépend bien sûr de vous.

Wouter Verhelst
la source
1
Je veux soutenir awk depuis des années dans l'un de mes plus grands projets gawk, mais le manque de recherche insensible à la casse déclenche que gawk en a fait un non-démarreur en raison du nombre de recherches insensibles à la casse exécutées. gensub est l'autre fonctionnalité uniquement gawk qui était trop difficile à remplacer dans awk. Mais gawk n'est pas toujours installé par défaut sur certaines machines et distributions, bien qu'il soit presque toujours disponible, mais il est regrettable qu'en 2016, ils ne pouvaient pas changer awk et posix pour étendre un peu les fonctionnalités de ces outils standard.
Lizardx du
3
@Lizardx: c'est tout l'intérêt de ne pas s'étendre: gardez-le standard. Sinon, vous créez simplement un autre standard, puis vous avez des incompabilités entre eux (ils le font, mais essayez de garder les changements de standard au minimum ... même alors, le standard multiple est l'un des principaux fléaux de l'informatique)
Olivier Dulac
2
Je ne suis pas d'accord. Avec une exécution minutieuse, vous pouvez introduire des extensions tout en prenant en charge toutes les méthodes héritées, ce qui se passe si vous ne le faites pas, c'est que les choses commencent juste à disparaître dans la non-pertinence au fil du temps. Tout en informatique évolue, l'astuce est de maintenir une évolution fiable très stable. Bash est un bon exemple de cela, super fiable et ajoute simplement de nouvelles fonctionnalités, ce n'est pas tellement `` deux normes '', utilisez ce qui est pris en charge, et une fois les modifications déployées à l'échelle mondiale, vous pouvez commencer à utiliser les nouvelles fonctionnalités car seul le les anciens systèmes hérités ne seront pas pris en charge.
Lizardx