Este recurso de destaque pode ser feito facilmente em grep
com --color
. Mas grep
não é possível fazer correspondência regular e invertida ao mesmo tempo , por exemplo grep foo -v bar ...
(preciso deste recurso, pois ele --color
só pode ser usado na entrada inicial do pipe |
, então o último grep usará os resultados coloridos que grep foo --color=always ... | grep -v "foo bar"
não removerão essas linhas com "foo bar").
Então eu usei awk
como as dicas do link acima, mas falta o recurso de destaque. Podemos extrair os resultados do regex com match
esubstr
onde envolvemos o padrão regex em match
como /\<no issue\>/
. Podemos então destacar apenas o resultado do regex com códigos de cores ANSI por printf substr($0,1,RSTART-1) "\033[1;31m" substr($0,RSTART,RLENGTH) "\033[0m: " substr($0,RSTART+RLENGTH) "\n"
.
P:
Mas match
não funciona para o boolean expr /foo/ && !/bar/
construído por regex exp's no link de referência. Existe uma solução alternativa elegante (talvez com outras ferramentas)?
Pensei em uma solução temporária /foo/ && !/bar/{match($0,/foo/); printf ...}
, mas isso fará com que o regex funcione duas vezes.
Meu comportamento esperado (Aqui 0. "TODO" pode existir no máximo uma vez em uma linha 1. Eu uso *...*
para mostrar o que deve ser destacado 2. Eu considero apenas /pattern1/ && !/pattern_included_totally_by_pattern1/
, então /foo/ && !/o/
oferecido por Ed Morton não é considerado. Isso é como a lógica grep, que eu primeiro grep some e então grep in aqueles resultados obtidos da execução grep anterior):
# fail
$ echo "TODO foo\nTODO" | grep TODO --color=always | grep -v "TODO foo"
*TODO* foo
*TODO*
# expected
$ echo "TODO foo\nTODO" | awk -v RED="\033[1;31m" -v RESET="\033[0m" '/TODO/ && !/TODO foo/ {match($0,/TODO/); printf substr($0,1,RSTART-1) RED substr($0,RSTART,RLENGTH) RESET substr($0,RSTART+RLENGTH) "\n"}'
*TODO*