Adding the modification time to the beginning of a file name

Today’s oddball chore was to try to rename a long series of files, all in one directory, with their modification date at the front of the name.

What I wanted was something like this, where the date is first, the hostname of the machine is second, and the last part of the name is the original file name.

I don’t have much of a rationale, but I used stat for this. ls will also spit out a nicely formatted list that has the date formatted properly.

However, I ran into problems with that and with cut, where the size of the file was shifting the location of the date from side to side.

Either way, here’s what I came up with:

for i in * ; do MODDATE=`stat -c "%y" "${i}" | cut -c-10` ; mv "$i" "$MODDATE $i" ; done

That should change, as an example, IMG_1346.JPG with a modification date of 2009-05-22, to “2009-05-22 IMG_1346.JPG” … hopefully.

If there’s an easier or cleaner way to do it, short of installing a renaming tool πŸ˜‰ , please let me know.

7 thoughts on “Adding the modification time to the beginning of a file name

  1. Kaleb Elwert

    Not much of a change. You just don’t need the temporary variable.

    for i in * ; do mv “$i” “$(stat -c “%y” “${i}” | cut -c-10) $i” ; done

    That should do the same thing. I’m sure there’s still a more efficient way, but this works.

  2. Duke

    Your problems with cut are the result of using absolution positioning (the ‘-c’ flag). I suggest that you try using “tr -s ‘[:blank:]’ | cut -d” ” -fx” instead, where x denotes the field number. In this way, tr will squeeze all repeated whitespace characters, and cut gives you the field number that you are interested. As an added advantage, x can be a range, such as 1-2 to select the first and second fields, or 3- to select the 3rd field and forward.

    Hope this helps,
    Duke πŸ™‚

  3. kgas

    another one [url=]here/url]

  4. Nate

    I prefer not having spaces in my file names, I’d separate the date from the rest of the file with an underscore. Here it is with cut

    SEP=”_”; for i in * ; do DATE=`ls -l $i | cut -d ‘ ‘ –fields=6`; mv $i “${DATE}${SEP}$i”; done

    or with awk

    SEP=”_”; for i in * ; do DATE=`ls -l $i | awk ‘{print $6}’`; mv $i “${DATE}${SEP}$i”; done

  5. Gavin Jones

    Here’s another way, which may be a little faster if there are a lot of files as it only calls stat once.

    stat -c “%n %y” * | while read f m x ; do
    mv “$f” “$m $f”


  6. IsaacG

    stat can give a seconds-since-epoch which GNU date can parse and spit out the desired format. (The @ means the date is in seconds-since-epoch format.)

    for i in * ; do
    mv “$i” “$(date +%F -d @$(stat -c%Y Grover_resume.pdf)) $i”

    Instead of cut, you can use awk and print out by field number rather than position.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s