awk '/^#[0-9]*$/ {split($0, arr, "#"); print "#", strftime("%c", arr[2]); getline; print }' < /path/to/.bash_history When HISTTIMEFORMAT is set, the command history of a Bash shell will be written to $HISTFILE, with comment lines of the timestamp of the command in epoch format, for example:
#1583857757 history #1583857774 grep HIST /etc/bashrc #1583857783 grep HIST /etc/skel/.bash_profile /etc/skel/.bashrc #1583857945 tail .bash_history The one-liner converts the epoch dates in this format into human readable dates to look like this:
# Tue 10 Mar 2020 04:29:17 PM UTC history # Tue 10 Mar 2020 04:29:34 PM UTC grep HIST /etc/bashrc # Tue 10 Mar 2020 04:29:43 PM UTC grep HIST /etc/skel/.bash_profile /etc/skel/.bashrc # Tue 10 Mar 2020 04:32:25 PM UTC tail .bash_history With awk '...' < /path/to/file we execute Awk commands in ..., using the content of /path/to/file as the input, with the < input redirection operator.
The first part of the Awk command /.../ is a filter: it matches lines in the input with the regular expression in .... The regular expression ^#[0-9]*$ matches lines that start with a "#", followed by zero or more digits until the end of the line.
For the matched pattern, Awk executes all the commands within the following { ... } block.
split($0, arr, "#") splits the line ($0) by #, storing the result in the array variable arrprint "#", strftime("%c", arr[2]) prints a line, starting with #, followed by a space, followed by the value of arr[2] formatted as s human readable time. arr[2] contains the timestamp in epoch format, notice that arrays in Awk use 1 as the starting index. If we take for example the input #123, then arr[1] is the empty string, and arr[2] is 123.strftime("%c", ...) formats a value as a human readable date. See man strftime for other possible formats.getline reads the next line of input and stores in the variable $0print simply prints the content of the variable $0