Perl Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesPerl Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here
  #1  
Old August 14th, 2000, 10:33 AM
whoopnstik whoopnstik is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2000
Location: Wheaton,IL USA
Posts: 9 whoopnstik User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
I want to write a loop (probably foreach) that will perform an action on each file in a certain folder. How would I do this?

Reply With Quote
  #2  
Old August 14th, 2000, 12:43 PM
JonLed JonLed is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Aug 2000
Location: Indiana
Posts: 614 JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 4 h 49 m 49 sec
Reputation Power: 9
$dir="/path/to/dir";
opendir(DIR, "$dir");
while($name = readdir(DIR)) {
##Put the names in an array, latest files 1st
unshift(@files, $name);
}
closedir(DIR);
}
##Remove "." and ".." (there are better ways to do this, but I didn't want to bother for this simple example)
pop(@files);
pop(@files);

foreach $name (@files) {
open(COUNT, "$dir/$name");
#This will put the data into an array
@data = <COUNT>;
close(COUNT);
#do whatever you want to the data now before reinserting it.. I just poped it.
pop(@data);
open(DATA, ">$dir/$name")
foreach $line @data {
print DATA "$linen";
}#end foreach
close(DATA);
}#end foreach

I didn't check to see if this works, but it should.

Reply With Quote
  #3  
Old August 14th, 2000, 12:48 PM
JonLed JonLed is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Aug 2000
Location: Indiana
Posts: 614 JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 4 h 49 m 49 sec
Reputation Power: 9
One thing to remember: This doesn't care if the "file" is a directory, or an actual file. For that you need to do an if(-f $dir/$file) type thing to see if it is a file before doing anything to it.

Reply With Quote
  #4  
Old August 14th, 2000, 08:14 PM
freebsd
Guest
Dev Shed Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
Another way of doing it which I believe is faster.

##### Just files in target_dir, files in subdirs of target_dir ignored #####

#!/usr/local/bin/perl

#enter the path, that is it.
$target_dir = "/path_here";

print "Content-type: text/htmlnn";
@ls = `ls -A $target_dir`;
foreach $file (@ls) {
@files = split (/s+/,$file);
foreach $result (@files) {
next if (-d "$target_dir/$result");
print "$result<br>n";
}
}
exit;


##### target_dir and all files in subdirs of target_dir #####

#!/usr/local/bin/perl

$target_dir = "/path_here";

print "Content-type: text/htmlnn";
@du = `du $target_dir`;
foreach $line (@du) {
($size,$dir) = split (/s+/,$line);
@ls = `ls -A $dir`;
foreach $file (@ls) {
@files = split (/s+/,$file);
foreach $result (@files) {
next if (-d "$dir/$result");
print "$result<br>n";
}
}
}
exit;


[This message has been edited by freebsd (edited August 14, 2000).]

Reply With Quote
  #5  
Old August 15th, 2000, 03:59 AM
christucker2 christucker2 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2000
Posts: 81 christucker2 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 8
A more canonical way to do this would be to use some of Perl's higher order functions -- specifically, grep and map. These allow you to apply a block of code to a set of values (kind of like an implicit foreach, but a lot shorter, sweeter, and less prone to errors). So, code to print out all of the files in a directory might look like this:

<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">code:</font><HR><pre>
my $dir = $ENV{HOME};
opendir DIR, $dir or die "Failed to open dir $dir";
my @file = map {print "$_n"} grep -f, map "$dir/$_", readdir DIR or die "Failed to open $dir/$_: $!";
closedir DIR;
[/code]

That looks a little intimidating at first, but if you analyse it it isn't so bad. Take a look at perldoc -f grep and perldoc -f map to get some info about those functions (and some examples of their use). It's trivial to adapt that code to perform more complex operations on each file. For example, the following will print out the number of lines in each file:

<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">code:</font><HR><pre>
my $dir = $ENV{HOME};
opendir DIR, $dir or die "Failed to open dir $dir";
my @file = map { print &linecount } grep -f, map "$dir/$_", readdir DIR or die "Failed to open $dir/$_: $!";
closedir DIR;

sub linecount {
return `wc -l $_`;
}
[/code]

These aren't tested, but should work (first one definitely, second will probably require a unix system). map and grep are two of the most powerful functions in the Perl language, and it's well worth getting to grips with them.

Reply With Quote
  #6  
Old August 15th, 2000, 06:43 PM
JonLed JonLed is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Aug 2000
Location: Indiana
Posts: 614 JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 4 h 49 m 49 sec
Reputation Power: 9
christucker2's is a little more detailed than what I thought he wanted. And freebsd's will always require a UNIX system to work.

I suggest not doing system command when at all possible to avoid OS incompatibilities.

Reply With Quote
  #7  
Old August 16th, 2000, 03:52 AM
christucker2 christucker2 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Aug 2000
Posts: 81 christucker2 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 8
Absolutely. If people didn't use system commands willy nilly in their perl code it would make life a lot easier... Only reason that second example of mine needs unix is for the wordcount example because I couldn't be arsed to write a real subroutine. :-) I would say that it makes sense for whoopnstik to try to learn about things like map and grep though, as they are a common way of achieving the result he/she's looking for in the Perl world, and he/she's likely to come across it again.

Reply With Quote
  #8  
Old August 16th, 2000, 10:43 AM
JonLed JonLed is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Aug 2000
Location: Indiana
Posts: 614 JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level)JonLed User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 4 h 49 m 49 sec
Reputation Power: 9
Agreed

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPerl Programming > perl file management


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway