3

When you use grep twice, the highlight from the first is stripped. As far as I can tell, this helps avoid matching the formatting codes. (For contrast, "ack-grep" will highlight new matches while preserving formatting in old matches as long as the matches don't overlap, but it will happily match the formatting codes used.) The behavior I'm looking for is pattern matching on the underlying text, as though formatting weren't there, but not at the cost of stripping formatting from the original for future display. Is this behavior built in somewhere? I have grep aliased with --color=always.

This may be a duplicate of Preserve colouring after piping grep to grep - however I'm also looking to find out why and how some programs strip formatting, and if it can be used to correct accidental escape code matching. (If this is solved or unsolveable I'll happily close it.)

Community
  • 1
  • 1
John P
  • 1,463
  • 3
  • 19
  • 39

1 Answers1

3

By default, in the .bashrc files, ls and grep are defined as alias. The alias are:

ls -> ls --color=auto
grep -> grep --color=auto

The auto option means that if stdout is the screen, it will show the output with colours, but if output is redirected to a pipe or a file, the colour formating will be erased. When you put the the option "--color=always", this forces to format with colour regardless where the output is redirected. You can also to never put any colour formatting using --color=never

You can check the alias by typing alias. You can also execute the plain ls or grep command (that is, no parameters given by aliases) appending a backslash at the beginning.

For example, with ls command:

\ls

Will show the output to screen without colours.

AwkMan
  • 670
  • 6
  • 18
  • Thank you... I'm not sure how to get the behavior I had in mind with this information, but it does help. If you had a grep piped to something else piped to another grep, only the last grep would color because the first one stripped/skipped color when it piped. Do you think there's a way to diff the colored and plain versions, operate on the plain one, and merge the deltas (escape codes) back in? I know this is more effort than it's worth without a more practical use case, but I feel like I'm missing something important with escape codes and stream editing. (...) – John P Aug 01 '16 at 21:27
  • Is there maybe a better way to pattern match and/or replace in "printed" characters while ignoring but preserving "un-printed" characters? – John P Aug 01 '16 at 21:34
  • So in general you can start looking for control codes and parse between them and the terminal character: I believe all (relevant) ones are between `\e[` and `m`. `\e[0m` or `\e[m` clears all formatting, but there are specific codes to reset FG/BG/bold/etc. like A`\e[1m`*B*`\e[2m`C. Those codes can be embedded in other codes, like bright (1) red (31) is `\e[1;31m`. If you go down this road, I recommend splitting up semicolon-joined codes, and replacing general resets with a reset for each open format, so formats all have clear beginnings and ends. – John P Sep 04 '22 at 17:51
  • I think I would most rather substitute all the escape codes with unused delimiters so the delimited content can be freely searched/modified and the escape codes can be read/modified in some other isolated context, e.g. getting the color red from the values of `\e[38;2;255;0;0m`. There are lots of ways to do this, but... honestly I can't shake the feeling that I'm reverse engineering content that was generated and only decorated at the last second. There's no way Grep searches the content a second time to add color, right? – John P Sep 04 '22 at 18:24