Add File Names with Time Stamp

P

Picker Leon

I have 1000 pictures files from digital camera. I want to rename the files
so that the file will have the time stamp so that I can know where I took
those pictures. If I FTP those files, the time stampe will always change etc
so I must include the time stamp into the filename. Here is what I want PERL
to do:

Dir the directory
Add each file's timestamp to the end of the file name.

Anyone knows a little script to do that work?
 
G

Gunnar Hjalmarsson

Picker said:
I have 1000 pictures files from digital camera. I want to rename
the files so that the file will have the time stamp so that I can
know where I took those pictures. If I FTP those files, the time
stampe will always change etc so I must include the time stamp into
the filename. Here is what I want PERL to do:

Dir the directory Add each file's timestamp to the end of the file
name.

Anyone knows a little script to do that work?

You can easily write it by help of these Perl functions:

readdir()
stat()
rename()
 
P

Picker Leon

Gunnar Hjalmarsson said:
You can easily write it by help of these Perl functions:

readdir()
stat()
rename()

Could you show me how? I have pictures all in 1 dir with will sit with this
perlscript. All are ending with JPG. Thank you.
 
T

Tad McClellan

Anyone knows a little script to do that work?


This isn't where folks talk about programs written in Perl.

This is where folks talk about _writing_ programs in Perl.

Write a Perl program that does the best you can, post
it here, and we will help you fix it.
 
P

Picker Leon

Here is what I wrote. Works 100%. But the only problem is if I have two
files with the same timestamp, it will overwrite it. Can you fix it? If the
rename to exit, then add a A to the end of the file
#############start
#!/usr/local/bin/perl
$some_dir='.';

opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
@dots = grep { /.jpg/ } readdir(DIR);
closedir DIR;

for (@dots) {

($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat($_);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime($mtime);
$year = sprintf("%02d", $year % 100);
$mon = sprintf("%02d", $mon % 100);
$mday = sprintf("%02d", $mday % 100);
$hour = sprintf("%02d", $hour % 100);
$min = sprintf("%02d", $min % 100);
$sec = sprintf("%02d", $sec % 100);

$new= "$year$mon$mday$hour$min$sec.jpg";
print "$new\n";
rename $_, $new;
}
#############end
 
P

Picker Leon

Fixed.
Change
rename $_, $new;
to
rename $_, $new if !stat($new);

Also you need to add 1 to the $mon.
 
B

Ben Morrow

[please don't top-post: it is considered rude]

Picker Leon said:
Here is what I wrote. Works 100%. But the only problem is if I have two
files with the same timestamp, it will overwrite it. Can you fix it? If the
rename to exit, then add a A to the end of the file
#############start
#!/usr/local/bin/perl

You missed the all-important
use warnings;
use strict;
$some_dir='.';

You will now need
my $some_dir = '.';
and similar for all the other variables.
opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
@dots = grep { /.jpg/ } readdir(DIR);

Here you want { /\.jpg$/ }.
closedir DIR;

for (@dots) {

($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat($_);

I would always be inclined to use File::stat: put
use File::stat;
at the top and then you can simply say
my $mtime = stat($_)->mtime;
..
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime($mtime);
$year = sprintf("%02d", $year % 100);
$mon = sprintf("%02d", $mon % 100);
$mday = sprintf("%02d", $mday % 100);
$hour = sprintf("%02d", $hour % 100);
$min = sprintf("%02d", $min % 100);
$sec = sprintf("%02d", $sec % 100);

Why are all these '% 100'? $year, OK, it's necessary; the others will
never be greater than 100 anyway.

I would use POSIX::strftime for this: put
use POSIX qw/strftime/;
at the top and then say
my $timestamp = strftime "%y%m%d%H%M%S", localtime stat($_)->mtime;
, but I know there are those in this group who wouldn't :).
$new= "$year$mon$mday$hour$min$sec.jpg";
print "$new\n";

I am assuming here that when you say 'at the end of the file' you mean
before the '.jpg'? :)
Here you want to add:

my $ext = "";
while(-e "$timestamp$ext.jpg") {
$ext++;
$ext = "A" if $ext == 1;
}
rename $_, $new;

rename $_, "$timestamp$ext.jpg";

There is a race condition here between the -e and the rename, which
basically means 'don't mess around and add files to the directory
while the script is running'.
}
#############end

Ben
 
M

Malcolm Dew-Jones

Picker Leon ([email protected]) wrote:
: Here is what I wrote. Works 100%. But the only problem is if I have two
: files with the same timestamp, it will overwrite it. Can you fix it? If the
: rename to exit, then add a A to the end of the file
: #############start
: #!/usr/local/bin/perl
: $some_dir='.';

: opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
: @dots = grep { /.jpg/ } readdir(DIR);
: closedir DIR;

: for (@dots) {

: ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
: $atime,$mtime,$ctime,$blksize,$blocks)
: = stat($_);
: ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
: localtime($mtime);
: $year = sprintf("%02d", $year % 100);
: $mon = sprintf("%02d", $mon % 100);
: $mday = sprintf("%02d", $mday % 100);
: $hour = sprintf("%02d", $hour % 100);
: $min = sprintf("%02d", $min % 100);
: $sec = sprintf("%02d", $sec % 100);

: $new= "$year$mon$mday$hour$min$sec.jpg";
: print "$new\n";
: rename $_, $new;

A very simple change that would work most of the time, and all the time if
you choose the syntax carefully.

rename $_, "$_-$new" or warn(qq{rename $_, "$_-$new" : $!});

The old name was unique, so the new name will _eventually_ be unique.

This can still overwrite a file, but choose a syntax for the new names
that you know will work. (e.g. if no files have two dashes in their names
then use two dashes in the new name).
 
M

Mahesha

Picker said:
I have 1000 pictures files from digital camera. I want to rename the files
so that the file will have the time stamp so that I can know where I took
those pictures. If I FTP those files, the time stampe will always change etc
so I must include the time stamp into the filename. Here is what I want PERL
to do:

Dir the directory
Add each file's timestamp to the end of the file name.

Anyone knows a little script to do that work?

I use Image::Info to get similar information from my digital pictures.
If your camera stores timestamp in the jpeg file, you could use this
method too. That way, even if you ftp your pictures, you can still get
the original timestamp.

http://search.cpan.org/~gaas/Image-Info-1.15/lib/Image/Info.pm

HTH,
Mahesh.
 
P

Picker Leon

for (@dots) {
I would always be inclined to use File::stat: put
use File::stat;
at the top and then you can simply say
my $mtime = stat($_)->mtime;

question. what is the difference between using File::stat as your way or the
one without as my war? Do I have to use File::stat before I can use my
$mtime = stat($_)->mtime;?

.


Why are all these '% 100'? $year, OK, it's necessary; the others will
never be greater than 100 anyway.

all %100 are must!!! for instance 11/03 and 01/13 wiill all get 113, so I
insist to use 2 digit for all month and day info.

I would use POSIX::strftime for this: put
use POSIX qw/strftime/;
at the top and then say
my $timestamp = strftime "%y%m%d%H%M%S", localtime stat($_)->mtime;
, but I know there are those in this group who wouldn't :).


I am assuming here that when you say 'at the end of the file' you mean
before the '.jpg'? :)
Here you want to add:

my $ext = "";
while(-e "$timestamp$ext.jpg") {
$ext++;
$ext = "A" if $ext == 1;
}

what is te ext for? if you have ext as '', then $timestampe$ext is nothing
but still $timestamp.
how can you ext++ a string? if you ''++ do you get 1 or A or what? can you
show me some reference to read about -e? thank you.

my scripts work 100% fine with my 1000 files. i am not sure if what you
added is a MUST or a Better, because I don't understand your concerns. Could
you give some example in which why your changed code is better and mine is
not working.
 
J

Jay Tilton

[Further author attributions lost.]

: > > for (@dots) {
: > >
: > > ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
: > > $atime,$mtime,$ctime,$blksize,$blocks)
: > > = stat($_);
: >
: > I would always be inclined to use File::stat: put
: > use File::stat;
: > at the top and then you can simply say
: > my $mtime = stat($_)->mtime;
:
: question. what is the difference between using File::stat as your way or the
: one without as my war?

You could try reading the File::stat documentation. The first line
explains it pretty well.

File::stat - by-name interface to Perl's built-in stat() functions

: Do I have to use File::stat before I can use my $mtime = stat($_)->mtime;?

Yes.

: > > ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
: > > localtime($mtime);
: > > $year = sprintf("%02d", $year % 100);
: > > $mon = sprintf("%02d", $mon % 100);
: > > $mday = sprintf("%02d", $mday % 100);
: > > $hour = sprintf("%02d", $hour % 100);
: > > $min = sprintf("%02d", $min % 100);
: > > $sec = sprintf("%02d", $sec % 100);
: >
: > Why are all these '% 100'? $year, OK, it's necessary; the others will
: > never be greater than 100 anyway.
:
: all %100 are must!!! for instance 11/03 and 01/13 wiill all get 113

How could any of those scalars ever contain the value "11/03" or "01/13" ?

Do you have any idea what localtime() returns?

: how can you ext++ a string? if you ''++ do you get 1 or A or what?

See "Auto-increment and Auto-decrement" in perlop.

: can you show me some reference to read about -e?

"-e" is one of the file test operators. See "-X FILEHANDLE" in perlfunc.
 
G

Gunnar Hjalmarsson

Picker said:
question. what is the difference between using File::stat as your
way or the one without as my war?

I suppose it's more about personal preferences.

What strikes me is that there is no reason to initiate all those
variables just to get the last modify time. Since you are only
interested in the 10:th element in the list generated by the stat()
function, this is how I would have done it (without File::stat):

my $mtime = (stat $_)[9];
all %100 are must!!! for instance 11/03 and 01/13 wiill all get
113, so I insist to use 2 digit for all month and day info.

The sprintf() function does that. The '%' operator is redundant
(except for $year).
 
B

Ben Morrow

Picker Leon said:
what is te ext for? if you have ext as '', then $timestampe$ext is nothing
but still $timestamp.

Yes. That is the point.
how can you ext++ a string?

Because Perl is cleverer (or mayber just DWIMer) than you think
:). Read the docs for '++' in perldoc perlop.
if you ''++ do you get 1 or A or what?

1. Hence my changing it to an 'A', which is what I wanted to
get. 'A'++, however, is 'B'.
can you show me some reference to read about -e? thank you.

perldoc -f -X
my scripts work 100% fine with my 1000 files.

I'm sorry, I assumed that since you were asking for help the script
was not working as you wished it to. I might think more than twice
about answering, next time.
Could you give some example in which why your changed code is better
and mine is not working.

Take a directory containing two files with the same timestamp. Run
your script. Start again; run mine. Observe the difference.

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top