|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
|
|
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
|
|||
|
|||
|
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?
|
|
#2
|
|||
|
|||
|
$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. |
|
#3
|
|||
|
|||
|
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.
|
|
#4
|
|||
|
|||
|
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).] |
|
#5
|
|||
|
|||
|
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. |
|
#6
|
|||
|
|||
|
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. |
|
#7
|
|||
|
|||
|
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.
|
|
#8
|
|||
|
|||
|
Agreed
|
![]() |
| Viewing: Dev Shed Forums > Programming Languages > Perl Programming > perl file management |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|