Sort by Mod Date
|
|
Thread rating:  |
J7y@Joimail.Com - 14 May 2004 00:19 GMT Hello,
I'm still extremely new to Perl, and was wondering if some of you might mind taking a peek at the code below and telling me if there's anything that could make it better or more efficient?
The code below is my attempt at grabbing the files from a folder and then sorting them by modification date.
Thanks for your insight.
Jay
-----
#!/usr/bin/perl
my $dir = "/Users/jay/Desktop/Other Stuff/old stuff 4";
opendir FOLDER, $dir or die "Cannot open $dir: $!";
foreach $file (readdir FOLDER) { next if $file =~ /^\./; $path = "$dir/$file"; next unless -f $path and -r $path; push @files, (stat $path)[9].chr(1).$path."\n"; }
@files = sort @files;
foreach (@files) { push @sortedList, (split(chr(1), $_))[1]; }
print @sortedList;
Ken Youens-Clark - 14 May 2004 01:22 GMT > Hello, > [quoted text clipped - 32 lines] > > print @sortedList; Jay,
This is a bit off-topic as your question isn't specific to MacOS and Perl; however, I can't resist a challenge nor the opportunity to help you learn Perl, so here's my offering:
#!/usr/bin/perl
use Cwd; use File::Find;
find( sub { -f $_ && -r _ && push @files, $File::Find::name }, shift || cwd() ); print join "\n", (sort @files), '';
The File::Find module can be a little cryptic, so you might be interested to look at Randal Schwartz's "File::Finder" module (not a standard module, so you'll have to install yourself). Also, File::Find will do a recursive search of directories by default, so you'll have to consult the docs (via "perldoc File::Find").
HTH,
ky
Chuck Rice - 14 May 2004 03:34 GMT >This is a bit off-topic as your question isn't specific to MacOS and >Perl; however, I can't resist a challenge nor the opportunity to help [quoted text clipped - 14 lines] >File::Find will do a recursive search of directories by default, so >you'll have to consult the docs (via "perldoc File::Find"). So to bring this back on topic, how do I
1) test to see if a found file is a Command-L created alias 2) test to see if the bundle bit is on (i.e. a special directory)
-Chuck-
 Signature Fight Spam! Join CAUCE! == http://www.cauce.org/
Sherm Pendley - 14 May 2004 04:03 GMT > So to bring this back on topic, how do I > > 1) test to see if a found file is a Command-L created alias > 2) test to see if the bundle bit is on (i.e. a special directory) Two ways:
You can use /Developer/Tools/GetFileInfo and parse its output.
Or, you can use Mac::Files, which is part of the Mac::Carbon package.
sherm--
David Cantrell - 20 May 2004 10:51 GMT > >So to bring this back on topic, how do I > > 1) test to see if a found file is a Command-L created alias > > 2) test to see if the bundle bit is on (i.e. a special directory) > you can use Mac::Files, which is part of the Mac::Carbon package. Is there any documentation anywhere on how to use this? It looks to me like just a list of constants.
 Signature David Cantrell | Reality Engineer, Ministry of Information
When a woman has a man on a string, controlling his every thought and motion, backbone in said man is not a requirement. -- Ken, in alt.2eggs...
David Cantrell - 14 May 2004 10:25 GMT > The File::Find module can be a little cryptic, so you might be > interested to look at Randal Schwartz's "File::Finder" module ... Or Richard Clamp's File::Find::Rule.
 Signature David Cantrell | Degenerate | http://www.cantrell.org.uk/david
With ... the fact that Linux has become so easy to install that certain species of bacteria are now being hired by MIS departments, what was once the domain of rigorously trained, highly specialized professionals has devolved into the Dark Land of the Monkeys. -- Greg Knauss
Ken Williams - 14 May 2004 03:53 GMT > #!/usr/bin/perl > [quoted text clipped - 14 lines] > push @sortedList, (split(chr(1), $_))[1]; > } Instead of using string-munging, you can use a real data structure:
------------ #!/usr/bin/perl
my $dir = "/Users/jay/Desktop/Other Stuff/old stuff 4";
opendir FOLDER, $dir or die "Cannot open $dir: $!";
foreach $file (readdir FOLDER) { next if $file =~ /^\./; $path = "$dir/$file"; next unless -f $path and -r $path; push @files, [(stat $path)[9], $path]; }
@files = map $_->[1], sort {$a->[0] <=> $b->[0]} @files;
print "$_\n" foreach @files; ------------
-Ken
Dan Kogai - 14 May 2004 04:18 GMT > Instead of using string-munging, you can use a real data structure: How come no one here is using hash?
#!/usr/bin/perl -Tw use strict; my $dir = shift || '.'; my %mtime; opendir my $dh => $dir or die "$dir:$!"; foreach my $f (grep !/^\./, readdir($dh)){ my $path = "$dir/$f"; # next unless -f $path and -r $path; # commented out $mtime{$path} = (stat($path))[9]; } closedir $dh; foreach my $f (sort {$mtime{$b} <=> $mtime{$a}} keys %mtime){ # print "$f\n" printf "%s $f\n", scalar(localtime($mtime{$f})); # prettier print } __END__
Dan the Camel (?:ab)user
P.S. FYI ls command has -t option that does just this
Matt Doughty - 14 May 2004 05:12 GMT here is my little bit for making a really short solution.
--Matt
#!perl my $dir = shift() || "."; opendir(DIR, $dir); print for(map { $_ . "\n" } sort { (stat($b))[9] <=> (stat($a))[9] } grep { !/^.{1,2}$/ } readdir DIR );
Joseph Alotta - 14 May 2004 05:46 GMT > here is my little bit for making a really short solution. > [quoted text clipped - 5 lines] > print for(map { $_ . "\n" } sort { (stat($b))[9] <=> (stat($a))[9] } > grep { !/^.{1,2}$/ } readdir DIR ); All these solutions are still too verbose and self-documenting. Can someone write something a little shorter, maybe a one-liner?
Joe.
Sherm Pendley - 14 May 2004 06:27 GMT > All these solutions are still too verbose and self-documenting. Can > someone write something a little shorter, maybe a one-liner? ls -lc | grep -v '^[ld].*'
Or did you want one line of Perl? ;-)
sherm--
Jarkko Hietaniemi - 14 May 2004 07:54 GMT >>here is my little bit for making a really short solution. >> [quoted text clipped - 5 lines] >>print for(map { $_ . "\n" } sort { (stat($b))[9] <=> (stat($a))[9] } >>grep { !/^.{1,2}$/ } readdir DIR ); \. needed here instead of .
> All these solutions are still too verbose and self-documenting. Can > someone write something a little shorter, maybe a one-liner? "Does it have to fit in 80 columns?" :-)
opendir(DIR, shift || ".") && print map { "$_->[1]\n" } sort { $a->[0] <=> $b->[0] || $a->[1] cmp $b->[1] } map { [ (stat($_))[9], $_ ] } grep { !/^\.{1,2}$/ } readdir(DIR)
Note the added cmp test in case timestamps compare equal.
Pity that opendir() doesn't return a dirhandle.
> Joe. J7y@Joimail.Com - 15 May 2004 03:04 GMT Thanks very much Ken, Ken, Dan, Matt, Sherm and Jarkko for your excellent examples! I really appreciate the time you've taken to share your code.
Hope you don't mind, but I have a few more questions. I've been researching through my Perl books and think I understand how most of the code below works, but I can't seem to make it work with my test folder items. Here's what I'm running:
opendir(DIR, shift || "/Users/jay/Desktop/Other Stuff/old stuff 4") && print map { "$_->[1]\n" } sort { $a->[0] <=> $b->[0] || $a->[1] cmp $b->[1] } map { [ (stat($_))[9], $_ ] } grep { !/^\.{1,2}$/ } readdir(DIR)
The different types of errors I'm getting are:
Argument (file name) isn't numeric in numeric comparison (<=>) (62) Use of uninitialized value in string comparison (cmp)
(I'm running this code in 'Affrus' on OS 10.3.3)
--
I'm also curious how 'grep' works in here. If I'm understanding part of it right, it looks like 'grep' is pulling just the lines (from the file names that have been read in) that don't start with a period. But I'm not sure how {1,2}$ works in there?
Thanks again for your help.
Jay
|
|
|