Pesquisa sem distinção entre maiúsculas e minúsculas no awk

20

Preciso procurar uma palavra-chave usando o awk, mas quero executar uma pesquisa que não diferencia maiúsculas de minúsculas (sem distinção entre maiúsculas e minúsculas).

Eu acho que a melhor abordagem é capitalizar o termo de pesquisa ("palavra-chave") e a linha de destino que o awk está lendo ao mesmo tempo. A partir desta pergunta, eu como usar toupperpara imprimir em maiúsculas, mas não sei como usá-lo em uma correspondência, porque essa resposta mostra apenas a impressão e não deixa o texto em maiúsculas em uma variável.

Aqui está um exemplo, dada esta entrada:

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

Eu gostaria desta saída:

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

É isso que tenho, mas não sei como adicionar toupper:

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

Respostas:

23

Substitua sua expressão para corresponder a um padrão (ou seja /&&&key word&&&/) por outra expressão usando explicitamente $0a linha atual:

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

ou

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

Então você tem

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

Você precisa de aspas simples por causa do $0, o bloco BEGIN pode ser removido como variáveis são inicializados por padrão para ""ou 0na primeira utilização, e {print}é a ação padrão, como mencionado nos comentários abaixo.

meuh
fonte
4
Observe que você pode simplificar isso para awk 'toupper($0)~/&&&KEY WORD&&&/ { p = ! p ; next } ; p;' text.txt. Não há necessidade do BEGINbloco e, como a ação padrão é imprimir, p;é suficiente.
terdon
11
"Não há necessidade do BEGINbloco", pois uma variável não inicializada é avaliada como falsa.
perfil completo de Glenn Jackman
Obrigado pelas otimizações. Normalmente, tento limitar minha resposta a alterações mínimas no original, mas é verdade que o novo resultado é muito mais rígido e legível.
meuh
2
Apenas uma observação: tolowerestá presente nos sistemas awk antigos (ou não tão antigos) (ex: AIX), mas touppernem sempre está disponível ^^.
Olivier Dulac
16

O gawk possui uma IGNORECASEvariável interna, que, se configurada como diferente de zero, faz com que todas as comparações de cadeias e expressões regulares não façam distinção entre maiúsculas e minúsculas. Você poderia usar isso:

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

etc. Isso é específico gawk, porém, mas acho que é mais legível do que a alternativa (mais portátil) do meuh. Se isso é um problema, é claro, depende inteiramente de você.

Wouter Verhelst
fonte
11
Eu queria apoiar o awk por anos em um dos meus maiores projetos gawk, mas a falta de pesquisa que não diferencia maiúsculas de minúsculas desencadeia que o gawk o tornou um iniciador devido ao número de pesquisas que não diferenciam maiúsculas de minúsculas. O gensub é o outro único recurso do gawk que era muito difícil de substituir no awk. Mas o gawk nem sempre é instalado por padrão em algumas máquinas e distribuições, embora quase sempre esteja disponível, mas é lamentável que em 2016 eles não pudessem mudar o awk e o posix para expandir um pouco a funcionalidade dessas ferramentas padrão.
Lizardx 01/04/19
3
@ Lagartox: esse é o objetivo de não expandir: mantenha-o padrão. Caso contrário, você apenas cria outro padrão e, em seguida, possui algumas incompatibilidades (eles fazem isso, mas tentam manter as alterações no mínimo ... mesmo assim, o padrão múltiplo é uma das principais pragas da computação)
Olivier Dulac
2
Eu não concordo Com uma execução cuidadosa, você pode introduzir expansões enquanto oferece suporte a todos os métodos herdados. O que acontece se você deixar de fazer isso é que as coisas começam a desaparecer na irrelevância ao longo do tempo. Tudo na computação evolui, o truque é manter uma evolução confiável muito estável. O Bash é um bom exemplo disso, super confiável e simplesmente adiciona novos recursos, não são apenas 'dois padrões', use o que é suportado e, depois que as alterações forem implementadas globalmente, você poderá começar a usar os novos recursos, porque apenas o os sistemas legados mais antigos não terão suporte.
Lizardx 01/04