Simple Filename Parsing Question
March 9, 2008 7:33 AM Subscribe
Should-be-simple Linux timestamped file parsing question.
I have a directory with what is now 10k jpeg files in this format (number of seconds since 1970):
1202499302.jpg
1202419201.jpg
1202439301.jpg
1202459401.jpg
1202479501.jpg
1202499602.jpg
1202419502.jpg
1202439601.jpg
1202459702.jpg
1202479801.jpg
1202499901.jpg
I'd like to use a script of some sort to shuffle these images into directories based on month, then day. Note that the "last modified" times on the file system are not necessarily the same as the timestamp in the file name, and I'd like to collate the files with the file name timestamp, not the filesystem timestamp.
Can anyone suggest a way to do this?
I have a directory with what is now 10k jpeg files in this format (number of seconds since 1970):
1202499302.jpg
1202419201.jpg
1202439301.jpg
1202459401.jpg
1202479501.jpg
1202499602.jpg
1202419502.jpg
1202439601.jpg
1202459702.jpg
1202479801.jpg
1202499901.jpg
I'd like to use a script of some sort to shuffle these images into directories based on month, then day. Note that the "last modified" times on the file system are not necessarily the same as the timestamp in the file name, and I'd like to collate the files with the file name timestamp, not the filesystem timestamp.
Can anyone suggest a way to do this?
Best answer: Run this Perl script with one argument, the path to the directory containing the JPG files. This version just prints the actions it would take. If you're satisfied with what you see, change the print calls to system calls and it will move the files for real.
posted by letourneau at 8:29 AM on March 9, 2008
#!/usr/bin/perl use File::Basename; my $dirname = $ARGV[0]; opendir(DIR, $dirname) or die "Couldn't open directory $dir: $!"; my $file; while (defined($file = readdir(DIR))) { my $basename = basename($file, ".jpg"); if ($basename !~ /[^0-9]/) { my ($sec, $min, $hrs, $day, $mon, $year, $wday, $yday, $dst) = localtime($basename); my $datetime = localtime($basename); my $realyear = $year + 1900; my $targetdir = "$dirname/$realyear/$mon/$day"; print("mkdir -p $targetdir\n"); print("mv $dirname/$file $targetdir/$basename.jpg\n"); } } closedir(DIR);
posted by letourneau at 8:29 AM on March 9, 2008
Never mind the spurious line my $datetime = localtime($basename); in there, I was trying something that didn't work. That's a leftover I forgot to delete before posting; you can delete it and the script will run exactly the same without it.
posted by letourneau at 8:31 AM on March 9, 2008
posted by letourneau at 8:31 AM on March 9, 2008
Ugh, and when you change the print calls to system calls, remove the \n's from the lines. Every time I post code to MetaFilter, I immediately find a half-dozen little nits I forgot to pick. Sheesh!
posted by letourneau at 8:39 AM on March 9, 2008
posted by letourneau at 8:39 AM on March 9, 2008
Response by poster: Thanks go to both of you -- the perl code worked wonderfully.
posted by yellowbkpk at 9:21 AM on March 9, 2008
posted by yellowbkpk at 9:21 AM on March 9, 2008
Take letourneau's script, and rather than edit it to s/print/system/, run it once to view, and if you like what you see, run it again and pipe into "sh -x" to execute what it says.
This is really handy as you can intermix commands and comments in your program output.
posted by devbrain at 10:17 AM on March 9, 2008 [1 favorite]
This is really handy as you can intermix commands and comments in your program output.
posted by devbrain at 10:17 AM on March 9, 2008 [1 favorite]
Best answer: You can do it this way in one line of shell:
for f in *.jpg; do t=${f%.jpg}; d=$(date -d @$t +%Y/%m/%d); echo "mkdir -p $d && mv $f $d/$f"; done
Note this won't work on OS X - you'd need to substitute "-r $t" for "-d @$t".
posted by sergent at 2:01 PM on March 9, 2008 [2 favorites]
for f in *.jpg; do t=${f%.jpg}; d=$(date -d @$t +%Y/%m/%d); echo "mkdir -p $d && mv $f $d/$f"; done
Note this won't work on OS X - you'd need to substitute "-r $t" for "-d @$t".
posted by sergent at 2:01 PM on March 9, 2008 [2 favorites]
This thread is closed to new comments.
posted by Mach5 at 8:17 AM on March 9, 2008