Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I would like to batch rename a bunch of files in a directory based on each file's individual date/time stamp. Basically, I get *.avi files off my camera that I want renamed to their date/time of origin (file date/time). The camera names them sequentially.
jhead works great for *.jpg files, but won't work for non-jpg files. mv won't look at the date/time stamp of the file.
I'm sure it is an easy thing to do, if I could just find the right command-line utility...
Wow! Seems like there should be a simpler more elegant way. I couldn't be the first one who wants to do such a thing, and that's a whole lot of bash scripting for such a simple job...
Did you just write this? Or have you used it before?
This is not complicated at all. Here's what it does:
- find files named "something.avi", whatever the case (AVI, avi, aVi...) and ask the "find" command to output the date+time, and the filename with path.
- for each date+time, and full path:
1/ get dirname, filename, and extension, along with an empty ssuffix.
2/ check if the name that we'll use is not already used, and if so rename the existing file with suffix "_00", and from there start an incremental naming: 01, 02, 03... (should be rare if not impossible, unless you mix photos from different cameras)
3/ do the actual renaming from the old name to the new one (timestamp + suffix (may be empty) + extension)
As for your question, I indeed wrote it just now, because I'm too lazy to go and fetch the one I wrote for my own usage.
By the way, I just see 1 error, which I'll correct just now in the original post.
...
Done.
As the script is saved in a file, you won't have to type it each time. So it is not different than using any command-line tool.
Yves.
Last edited by theYinYeti; 09-03-2006 at 02:40 PM.
Well, I did tests, and good that I did.
Here is the final version of the script with no errors:
Code:
#!/bin/bash
place="${1:-.}"
ext="${2:-avi}"
files="$(find "$place" -type f -iname "*.$ext" -printf "%T+ %p\n")"
while read ts f; do
d="$(dirname "$f")"
f="$(basename "$f")"
e="${f##*.}"
s=
if [ -e "$d/$ts.$e" ] || [ -e "$d/${ts}_00.$e" ]; then
[ -e "$d/${ts}_00.$e" ] || mv "$d/$ts.$e" "$d/${ts}_00.$e"
s=01
while [ -e "$d/${ts}_$s.$e" ]; do
s=$(awk '{printf "%02u", $1+1}' <<<"$s");
done
s=_$s
fi
echo "D: $d - F: $f - E: $e - S: $s => $d/$f -> $d/$ts$s.$e"
mv "$d/$f" "$d/$ts$s.$e"
done <<<"$files"
I had forgotten some braces...
Besides, now you can choose the extension:
./date_rename.sh /some/dir
will rename inside the directory AVI files.
./date_rename.sh /some/dir mov
will rename inside the directory MOV files.
This time it is tested to some degree. Try with test files, though; it is always safer
Yves.
[edit:]The "echo" command at the end is purely optional (you can remove it). I used it for debug purposes, but I left it there as it tells you what it is doing.[/edit]
Last edited by theYinYeti; 09-04-2006 at 04:14 AM.
Well, I did tests, and good that I did.
Here is the final version of the script with no errors:
Code:
#!/bin/bash
place="${1:-.}"
ext="${2:-avi}"
files="$(find "$place" -type f -iname "*.$ext" -printf "%T+ %p\n")"
while read ts f; do
d="$(dirname "$f")"
f="$(basename "$f")"
e="${f##*.}"
s=
if [ -e "$d/$ts.$e" ] || [ -e "$d/${ts}_00.$e" ]; then
[ -e "$d/${ts}_00.$e" ] || mv "$d/$ts.$e" "$d/${ts}_00.$e"
s=01
while [ -e "$d/${ts}_$s.$e" ]; do
s=$(awk '{printf "%02u", $1+1}' <<<"$s");
done
s=_$s
fi
echo "D: $d - F: $f - E: $e - S: $s => $d/$f -> $d/$ts$s.$e"
mv "$d/$f" "$d/$ts$s.$e"
done <<<"$files"
I had forgotten some braces...
Besides, now you can choose the extension:
./date_rename.sh /some/dir
will rename inside the directory AVI files.
./date_rename.sh /some/dir mov
will rename inside the directory MOV files.
This time it is tested to some degree. Try with test files, though; it is always safer
Yves.
[edit:]The "echo" command at the end is purely optional (you can remove it). I used it for debug purposes, but I left it there as it tells you what it is doing.[/edit]
Last edited by theYinYeti; 09-04-2006 at 04:14 AM.
This is a clever idea. However, you'll have to refine it if spaces are allowed in the involved paths or file names, or if several files may happen to be created at the same second.
@unSpawn:
You're using a non-GNU or too-old version of find. You'll have to replace '%T+' with '%TY-%Tm-%Td+%TH:%TM:%TS' or any alternative you like.
This is a clever idea. However, you'll have to refine it if spaces are allowed in the involved paths or file names, or if several files may happen to be created at the same second.
It's actually spawnys :} ... I just happened to type it having seen
what he intended to do ;}
Code:
find -type f -name "*avi" -printf "mv \"%h/%f\" \"%h/%TY%Tm%Td-%TH%TM%Ts.avi\"\n"
It's actually spawnys :}
No, can't take credit for that: never intended to solve it that way.
So it actually is your own idea :-] And a neat one at that.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.