Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / Perl / May 2004



Tip: Looking for answers? Try searching our database.

Sort by Mod Date

Thread view: 
Enable EMail Alerts  Start New Thread
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
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.