Categories
Dev

Prefix CLI output

When interacting with the command line or writing automated scripts it’d be useful to prefix the output with the date or something equivalently useful. If you are a Linux or Terminal user you’ve probably come across the pipe symbol | , which for example allows you to apply grep filters, but it is not entirely clear how to prefix constant strings or dynamically evaluated commands like the date.

The following example shows how you’d use the pipe to filter multiple lines, to find a specific keyword

> echo -e "Lorem ipsum dolor\nfoo\nbar"
Lorem ipsum dolor
foo
bar
> echo -e "Lorem ipsum dolor\nfoo\nbar" | grep foo
foo

Prefix string

Similarly you can add text before or append text to each line using the sed text substitution command. The general structure of the command is ‘s/textToReplace/replaceWithThis/‘. However, we’re not substituting anything, instead we instruct it to prefix using the carot symbol ^.

# prefix with "Hello "
> echo World | sed 's/^/Hello /' 
Hello World

Prefix computed value

It is possible to prefix a dynamically evaluated command. To do so we need to add an evaluated string to our string replacement sed command. First, open the sed command by using single quotes, then we need to wrap the command we want to evaluate in double- and single-quotes "`COMMAND`" .

Single, double and back-tick quotes?

single quotes
retain literal value of each single character inside

double quotes
retain literal content except content that will be evaluated, like dollar signs or back-ticks

back ticks
an older style to trigger evaluation of it’s content. Nowadays the use of $( ) is more common

More information about quote types can be found: on this Stackoverflow post; information about backticks; the single and double quotes gnu docs
# example on how to insert a `COMMAND`
> echo World | sed 's/^/'"`COMMAND`"'/'
         literal value / | \ evaluate 
                  retain content
# equivalent $( ) command
> echo World | sed 's/^/'"$(COMMAND)"'/'

For improved readability I will use $( ) instead of back ticks.

# prefix with "Hello " and date
> echo World | sed 's/^/'"$(date)"' Hello /'
So 21 Jun 2020 22:21:39 MDT Hello World
# prefix with "Hello " and ISO 8601 date
> echo World | sed 's/^/'"$(date -u +"%Y-%m-%dT%H:%M:%SZ") "'Hello /' 
2020-06-22T04:16:04Z Hello World

Please note that the date is formatted with ISO 8601. I highly recommend that you consider formatting all dates with this standard, because you will do your future self or everyone else a favor by knowing what time formatting you used!
date -u +"%Y-%m-%dT%H:%M:%SZ"

TL;DR

To sum up, using the example above, we can use the pipe and the sed command to prefix each line with the date and “Hello “

> echo -e "Lorem ipsum dolor\nfoo\nbar" | sed 's/^/'"$(date -u +"%Y-%m-%dT%H:%M:%SZ") "'Hello /'
2020-06-22T05:00:34Z Hello Lorem ipsum dolor
2020-06-22T05:00:34Z Hello foo
2020-06-22T05:00:34Z Hello bar

Let me know if you find this useful or please share any alternative ways to prefix.


Also published on Medium.