Re: Open a folder
by choroba (Cardinal) on Jan 08, 2013 at 09:34 UTC
|
You can achieve your goal even without "opening" the folder:
for my $file (glob 'C:/Users/ZB/Desktop/Text\ Files/*.txt') {
calculate($file)
}
Update: Note the slashes separate the path elements and the backslash quotes the space.
| [reply] [d/l] |
Re: Open a folder
by vinoth.ree (Monsignor) on Jan 08, 2013 at 10:37 UTC
|
Opening the directory
To open the directory,use a function called "opendir". You use this same like the open function to open files. Below example shows opening of /tmp directory.
#!/usr/bin/perl
use strict;
use warnings;
my $tmp_dir="/tmp";
opendir (DIR, $tmp_dir) or die $!;
Reading the directory
To read the files and directories in the directory we use the readdir function. readdir returns the name of each file or directory in the opened directory in turn when used in scalar context, or a list of the names of all files and directories in that directory when used in list context. This means that we can use readdir in a foreach loop or any other loop
while (my $file_name = readdir(DIR)) {print "$file_name\n";}
Closing the directory
We use the function closedir to close the directory once we are finished with it. Like files, the directory will be closed when the program finish, but sometimes need to close the directory opened
closedir(DIR);
| [reply] [d/l] [select] |
|
Hi
This is the first progress I've made in some time, so thank you very much. When I run your code I get a list of all the file names within my directory. However I want open these text files as well, and then do some basic calculations(I have put these in a sub) in them. How can I iterate through all the text files within the directory and run my sub on each file?
| [reply] |
|
With the example you've been given there's a print statement within a while loop. Replace the print statement with the actions you wish to be taken, checking it's a text file, performing the operations you want. http://learn.perl.org, tutorials.
| [reply] |
|
#!
use strict;
use warnings;
use File::Find;
use Digest::MD5::File;
no warnings "File::Find";
use Smart::Comments;
local *wanted=sub {
if (-d $File::Find::name) { # directory
}
elsif ($File::Find::name =~ m{\.txt$}i) { # a file of interest
print "for $File::Find::name - @{[_SizeAndMD5($File::Find::nam
+e)]}\n";
}
}; # wanted
# Do something based on the file's content
local *_SizeAndMD5=sub {
my ($filename_S)=@_;
return (-e $filename_S ? sprintf("%8.8lx-%32.32s",-s $filename_S,D
+igest::MD5::File::file_md5_hex($filename_S)) : undef);
}; # _SizeAndMD5:
File::Find::find({ no_chdir=>1,wanted=>\&wanted },@ARGV);
exit;
This will process all of the files with a ".txt" extension below the directories specified by @ARGV. | [reply] [d/l] |
|
Hi Dr Manhattan
Below code process each files in the /tmp directory. If any directory is inside the /tmp directory will not be processed
Add additional checking on file, like file size and readable permissions to avoid error.
#!/usr/bin/perl
use strict;
use warnings;
my $tmp_dir="/tmp/";
opendir (DIR, $tmp_dir) or die $!;
while (my $file_name = readdir(DIR))
{
my $abs_path = $tmp_dir.$file_name;
unless(-d $abs_path) #Ignore if it is a directory
{
&Process_EachFile($abs_path); # Do call a function and process
+ each file
}
else
{
print "$abs_path is a directory\n";
}
}
closedir(DIR);
sub Process_EachFile
{
my ($filename) = @_;
print $filename;
open (FH,'<',"$filename") or die $!;
while(my $each_line=<FH>)
{
print $each_line."\n";
#Read file content here and do your calculation.
}
}
| [reply] [d/l] |
|
|
Re: Open a folder
by sen (Hermit) on Jan 08, 2013 at 09:34 UTC
|
| [reply] |
Re: Open a folder
by nithins (Sexton) on Jan 08, 2013 at 10:03 UTC
|
use opendir function , it will help i belive for example
#!/usr/bin/perl
use strict;
use warnings;
my $dir ="./files";
opendir ( DIR, $dir ) || die "Error in opening dir $dir\n";
while( (my $filename = readdir(DIR))){
print "$filename\n";
open (FH,'<',"./files/$filename");
while(<FH>){
##do your task here}
}
| [reply] [d/l] |
|
Your use of a global filehandle 'FH' inside a loop isn't a great idea. If the open fails then the nested while loop will use the already open handle FH which was left open to whatever file was opened last. Also since you've taken the trouble to define $dir why not use it when you open the file?
open (my $fh,'<',"$dir/$filename") or die " ... $!";
Another thing to watch out for is the directories '.' and '..'. Your code will pass these into $filename and attempt to open them. Use the file test -d $filename to skip directories. Or use -T $filename to find text files and ignore everything else.
A final suggestion is to use indentation inside loops and control blocks to help you keep track of the open and close curly braces.
| [reply] [d/l] [select] |
Re: Open a folder
by blue_cowdawg (Monsignor) on Jan 08, 2013 at 14:04 UTC
|
but I am struggling to open a folder using Perl.
Dear Monk,
First, excuse the professor in me, let me make a minor correction to the terminology you are using. What you refer to as a "folder" is actually a directory and Perl provides a wonderful function for reading directories. Here is some sample code to help you along your way:
#!/usr/bin/perl -w
use strict;
my $dirname="/path/to/the/directory";
opendir(DIR,$dirname) or die "$dirname:$!";
while (my $entry=readdir(DIR)){
next if $entry eq '.';
next if $entry eq '..';
next if -d $entry; # see notes below
| do something with this...
}
exit(0);
the -d $entry is to prevent you from attempting to do something unintended with a subdirectory under the desired directory. After you get past all the next logic (which could have been combined in one statement) you then add your code to actually do something with the file names you would get as a result of the rest of the code.
If you want to recursively operate on that directory here is an example of that code well modified:
#!/usr/bin/perl -w
use strict;
workTheDirectory("/path/to/the/directory");
exit(0);
#
#
sub workTheDirectory {
my $dirname=shift;
opendir(DIR,$dirname) or die "$dirname:$!";
while (my $entry=readdir(DIR)){
next if $entry eq '.';
next if $entry eq '..';
if ( -d $entry ) {
my $newdir = $dirname . "/" . $entry; #grow the path
workTheDirectory($newdir);
}
| This is a file...
| work it.
}
return;
}
Clear as mud?
Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
| [reply] [d/l] [select] |
|
next if $entry eq '.';
next if $entry eq '..';
did help. I have combined your code with something of another user to come up with this:
#!/usr/bin/perl -w
use strict;
use warnings;
open (Output, ">Output.txt") or die "Can't open";
my $tmp_dir= 'C:\Users\ZB\Desktop\Text Files';
opendir (DIR, $tmp_dir) or die $!;
while (my $file_name = readdir(DIR))
{
next if $file_name eq '.';
next if $file_name eq '..';
print "$file_name\n";
}
close (Output)
closedir(DIR);
All it does is print all the file names in my directory as output(so at least I am on the right path). However I want to iterate through each text file and do some basic calculations(all in 1 sub) within each file. Any ideas? | [reply] [d/l] [select] |
|
see perldoc -f push and Tutorials (below the text explaining how to/when to post a new tut) or Super Search re iterating through arrays.
IOW, collect all the relevant $file_name entries into an array; at that point, iterating thru the individual files requires only that you attempt to inform yourself thru study of the references above.
Update: Of course (/me says belatedly), you'll need to consider executing your script from an appropriate directory or troubling yourself to learn about perldoc -f chdir, perldoc cwd, etc.
| [reply] [d/l] [select] |
|
| in your while loop invoke:
process_file($tmp_dir,$file);
| and then after your loop
sub process_file {
my($path,$node)=@_;
my $fname = $path . '\' . $node;
open FIN,"<$fname" or die "$fname:$!";
while (my $line=<FIN>){
chomp $line;
| do something here.
}
}
Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
| [reply] [d/l] |
|
|
|
The advantage of your "correction" is clear. However, note that "folder" is the correct terminology for that structure in windows. The OP has consistently explained the problem from an application view.
| [reply] |
|
BillKSmith
Correct terminology, perhaps, if you buy (hook, line and sinker) M$'s (non-standard) terminology as an acceptable standard.
| [reply] |
|
| [reply] |
Re: Open a folder
by Anonymous Monk on Jan 08, 2013 at 10:50 UTC
|
#!/usr/bin/perl --
use Cwd;
use File::Find::Rule;
my @dirs = ( cwd() );
my @textfiles = find( 'file', 'name', qr/\.txt$/i, 'maxdepth', 1, 'in', \@dirs );
| [reply] |