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.
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.
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 🙂
another one [url=http://www.linuxjournal.com/video/renaming-groups-files-command-line]here/url]
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
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”
done
Gavin
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”
done
Instead of cut, you can use awk and print out by field number rather than position.
Darn. Where Grover_resume.pdf is a test file and ought to read “$i”