I would like to highlight a few literal strings while outputting a text file. For example highlighting [2]
, quick
and lazy
in:
... => any number of lines with non-matching content
He’s quick but lazy.
...
• The future belongs to those who believe in the beauty of their dreams [2].
...
I’m lazy but quick (2 times faster); is there a difference when "lazy" comes before "quick"?
...
My intuitive approach would be to use grep
for the colorization (in fact I'm not fixed on any specific tool):
grep -F -e '[2]' -e 'quick' -e 'lazy' --color file.txt
But it has two problems:
It filters out the lines that don't match while I want to include them in the output.
It doesn't highlight all the matching strings; it seems like the order in which the
-e
expressions are provided matters edit(with BSDgrep
).
My expected output, with the <...>
representing the colorisation, would be:
... => any number of lines with non-matching content
He’s <quick> but <lazy>.
...
• The future belongs to those who believe in the beauty of their dreams <[2]>.
...
I’m <lazy> but <quick> (2 times faster); is there a difference when "<lazy>" comes before "<quick>"?
...
CodePudding user response:
grep -n -F -e '[2]' -e 'quick' -e 'lazy' --color=always file.txt |
awk -F':' '
FILENAME==ARGV[1] { n=substr($1,9,length($1)-22); sub(/[^:] :/,""); a[n]=$0; next }
{ print (FNR in a ? a[FNR] : $0) }
' - file.txt
would use grep
to find and highlight the strings, and then awk
would print the grep
output for those lines and the original lines from the input file otherwise.
CodePudding user response:
I found a way with grep -E
instead of grep -F
; therefore the literal strings will require ERE-escaping.
The trick is to create a single regex with the union of each searched string, plus the anchor ^
which would select the "non-matching" lines.
So, for highlighting the string literals [2]
, quick
and lazy
in the text you can use:
grep -E '\[2]|quick|lazy|^' --color file.txt