Bash Autocomplete – Autocomplete Newest File

autocompletebash

I have a process which creates text files whose filenames are based on the timestamp of their moment of creation:

$ ls
1378971222.txt
1378971254.txt
1378971482.txt
1378971488.txt
1378972089.txt
1378972140.txt
1378972141.txt
1378972153.txt
1378972155.txt
1378972241.txt

How might I auto-complete the filename of the latest created file, i.e. the file with the latest mtime? There is no way to use Tab-completion for these files as almost every character in the filename is shared with another file. I am hoping to find a shortcut (such as Alt . which autocompletes the last argument of last command). I have managed to concoct the following alias which is great for VIM, but I would love to know if a general-purpose shortcut exists that I could use with kde-open, sqlite3, and other applications.

alias lastest="vim `ls -t | grep -vE "^total [0-9]*$" | head -n1`"

Best Answer

Just remove the vim from the alias. Do something like this:

alias latest='ls -tr | tail -n 1'

You can then use any program to open the latest files:

emacs `latest`
ls `latest`
mv `latest` ../

etc.

However, this will break if your file names have spaces or weird characters which is why you should never parse ls. A better way would be something like this (add this to your .bashrc) :

function latest(){
  $1 "$(find . -type f -printf "%C@ %p\n" | sort | tail -n 1 | cut -d " " -f 2-)"
}

This function will execute whatever command you give it as an argument and pass the result of the find call (the latest file) to that command. So, you can do things like:

latest emacs
latest less

If you need to be able to do things like mv $(latest) foo/ try this one instead:

function latest(){
   A=(${@})
   prog=$1;
   lat=$(find . -type f -printf "%C@ %p\n" | sort | tail -n 1 | cut -d " " -f 2-)
   if [ ! -z $2 ] ; then 
     args=${A[@]:1}; 
     $prog "$lat" "${A[@]:1}"
   else
     $prog "$lat"
   fi
}

Then, to copy the latest file to bar/, you would do

latest cp bar

And you can still do latest emacs in the same way as before.

Related Question