bashsorting

Sort `.bash_history` by timestamp


I've enabled the timestamp for my .bash_history by using the HISTTIMEFORMAT="%d.%m.%y %T " instructive in .bashrc. However, sometimes the order of the entries in the .bash_history is messed up, and I want to sort that file by the timestamp. Unfortunately, the timestamp is not in the same line as the entry, but one line above, like this:

#1512649029
a command
#1512649032
another command
#1512649039
a third command

So how can I sort the file by these "pairs" of lines? Furthermore, there are entries that have no timestamps, e.g. lines that have no #... line above. I want these lines to gather at the top of the file. Thanks!


Solution

  • Disclaimer: This might not be the most elegant and simplest solution. However the following bash shell script snippet worked for me:

    #!/bin/bash
    function BashHistoryJoinTimestampLines() {
        COMMAND_WITHOUT_TIMESTAMP=TRUE
        while read line; do 
            if [ "${line:0:1}" = "#" ] # This should be a timestamp line
            then echo -ne "$line\t" # the -n option supresses the line feed
                 COMMAND_WITHOUT_TIMESTAMP=FALSE
            else if [ ${COMMAND_WITHOUT_TIMESTAMP} = TRUE ]
                 then echo -ne "#0\t"
                 fi
                 echo $line
                 COMMAND_WITHOUT_TIMESTAMP=TRUE
            fi
        done 
    }
    #
    # Example:
    BashHistoryJoinTimestampLines < $HISTFILE | sort
    

    In Unix/Linux text processing by pipelining the sort utility program by default operates on records separated by line endings.

    In order to use "sort" for this application the timestamp lines have to be first joined together with the history lines containing the commands. Lines not preceeded by a time stamp will get a dummy timestamp of #0 (January 1st 1970) in this script. I've used the TAB character as a separator between timestamp and command in this script.