Ask Ubuntu is a question and answer site for Ubuntu users and developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This question already has an answer here:

I have 200 files in a folder which I downloaded. I downloaded them in a certain order -- often only a few seconds apart. I would like to append a number to the beginning of each of the files.

So the first file I downloaded (the oldest one) would need to change from name.txt to 001_name.txt. All the way up to the last file (most recently downloaded) changing from name.txt to 200_name.txt.

Is this possible to do using the terminal (as a batch)? Many thanks in advance.

share|improve this question

marked as duplicate by Anwar Shah, Afshin Hamedi, Eric Carvalho, Fabby, karel Jan 25 '15 at 2:07

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

up vote 4 down vote accepted

The following will break on files containing newlines, but should work the rest of the time. It will sort the files based on the time they were last modified, rather than their actual creation time, because Ubuntu doesn't store the creation time of files. So if you've modified the files since you downloaded them, you won't get an accurate ordering.

n=0; ls -tr | while read i; do n=$((n+1)); mv -- "$i" "$(printf '%03d' "$n")"_"$i"; done

ls -tr sorts files by modification time, oldest first (and when you pipe the output of ls it automatically lists files one-per-line rather than the standard way of doing things -- it should be noted that this is a GNU-ism, if you have to work on another *nix with a different version of ls, this might not be the case). while read i takes that list and goes over each item one at a time, and the rest of it does the actual renaming.

n=$((n+1)) increments the variable $n by one. There could be problems if this had been set beforehand, so to be on the safe side you should set it to 0 at the beginning of the line.

$(printf '%03d' "$n") prints the number contained in the variable $n, padded to three zeros (so 001, 002 ... 087 ... 999). I hope that the mv command is fairly obvious.

share|improve this answer
Don't use sort -r. It will mess up ls -t. In fact ls -t | sort -r is equivalent with ls | sort -r. Use lt -tr only! – Radu Rădeanu Sep 25 '13 at 14:33
Thank you for your reply. For some reason it doesn't put it in the right order. However I tried it without sort -r and that does put it in the correct reverse order. Perhaps there's something unusual about sort -r. – fushsialatitude Sep 25 '13 at 14:34
@RaduRădeanu so what should the correct statement be? – fushsialatitude Sep 25 '13 at 14:36
I think it should be ls -tr | while read i; do n=$((n+1)); mv -- "$i" "$(printf '%02d' "$n")"_"$i"; done – fushsialatitude Sep 25 '13 at 14:37
Thank you @RaduRădeanu -- I should have checked to see if ls has its own reversing, that saves a pipe. Looking at the sort man page, I can see what you mean, that was a silly mistake. @fushilatitude you are correct, that is the right way of doing it. – evilsoup Sep 25 '13 at 14:41

The following script will do the job:


if [ $# -ne 1 ];then
  echo "Usage: `basename $0` DIRECTORY"
  exit 1

ls -tr $@ | while read file; do
    if [ $count -lt 10 ]; then
        mv -v $file '00'$count'_'$file
    elif [ $count -lt 100 ]; then
        mv -v $file '0'$count'_'$file
        mv -v $file '0'$count'_'$file

This I just test it and it's worked for me.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.