Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find And Replace Current Text to Wrap In Color

Tags:

bash

sed

colors

zsh

So I'm trying to make an alias for cal that will run it through sed to wrap the current day in the terminal escapes for red.

cal | sed "s/($(date +%d))/\\033\[94m$(date +%d)\\033\[0m/g"

However, I apparently can't use inline command execution like $(date +%d) inside of a capture group.

In addition, if I use the command substitution in both place, I can get the replacement to work, but not the backslashes to escape the color code.

$ cal | sed "s/$(date +%d)/\\033\[94m$(date +%d)\\033\[0m/g"
      May 2016
Su Mo Tu We Th Fr Sa
 1  2  3  4  5  6  7
 8  9 10 033[94m11033[0m 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

Is there a way to wrap a replacement in colors? In addition, is there a better regex to handle single digit days? (Since on the first through ninth days of the month, it will highlight every instance of that number on the calendar.)

EDIT: I'm running OS X, Darwin Kernel Version 15.2.0, since apparently the cal implementation on OS X doesn't support the -h option.

like image 394
Brandon Anzaldi Avatar asked Oct 23 '25 14:10

Brandon Anzaldi


1 Answers

Try:

cal -h | sed "s/$(date +%d)/"$'\033\[94m&\033\[0m/g'

Notes:

  1. By default, cal highlights the current day. I used the -h option to turn that off so it doesn't interfere with your preferred color. [Update: apparently this applies to GNU cal only]

  2. You are right that $(date +%d) has to appear in double-quotes. The rest of the command, however, does not. Above, I used bash's $'...' for the rest of the command because it supports escape sequences.

  3. There is no need for a second $(date +%d). We can recall the matched text with &.

  4. If you have GNU sed, a convenient way to fix the single-digit day issue is to require the matched text to be a whole word using \<...\>:

    cal -h | sed "s/\<$(date +%d)\>/"$'\033\[94m&\033\[0m/g'  # GNU
    

    If your sed does not have that feature, you will need to s commands:

    cal -h | sed "s/ $(date +%d) /"$'\033\[94m&\033\[0m/g; '"s/ $(date +%d)$/"$'\033\[94m&\033\[0m/g'
    

    The first substitute command looks for the date surrounded by spaces. This works for all single digit dates except the ones at the end of a line. The second looks for dates preceded by a space and followed by the end of the line ($).

like image 183
John1024 Avatar answered Oct 25 '25 05:10

John1024