Shell commands with GNU sed Steckerhalter's ƛ

sed is useful to replace some text on the fly. But how about processing text on the fly with shell commands instead of just replacing it with fixed content?

GNU sed can do that. For example if you have a .bash_history in raw format:

$ cat .bash_history
#1484399389
history 
#1484399397
vim .profile 
#1484399415
cat .bash_history 
#1484399431
ls
#1484399447
echo nice try 

The time stamps are unix epoch time (number of seconds since 1970). To convert them to real dates on the fly, we can use sed substitute with (from info sed):

'e'
     This command allows one to pipe input from a shell command into
     pattern space.  If a substitution was made, the command that is
     found in pattern space is executed and pattern space is replaced
     with its output.  A trailing newline is suppressed; results are
     undefined if the command to be executed contains a NUL character.
     This is a GNU 'sed' extension.

like so:

$ cat .bash_history | sed -r 's/^#([0-9]+).*/date --date="@\1"/e'
Sam Jan 14 14:09:49 CET 2017
history 
Sam Jan 14 14:09:57 CET 2017
vim .profile 
Sam Jan 14 14:10:15 CET 2017
cat .bash_history 
Sam Jan 14 14:10:31 CET 2017
ls
Sam Jan 14 14:10:47 CET 2017
echo nice try 

With the regex ^#(0-9)+.* we capture the number of seconds and then feed that into the date command.

For example:

date --date="@1484399389"

outputs:

Sam Jan 14 14:09:49 CET 2017

It converts the unix epoch in seconds into a human readable date. In combination with sed this is done on-the-fly.

Quite useful.