Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Reading Multiple files

by maheshkumar (Sexton)
on Aug 07, 2012 at 11:42 UTC ( #985943=perlquestion: print w/replies, xml ) Need Help??
maheshkumar has asked for the wisdom of the Perl Monks concerning the following question:

I need some help with this, I have written a code which takes in input of multiple files and then it is supposed to process each file and save its output in a seperate file for each, but what is happening is that everytime i run the program it takes the new file created as the input as well. And for example my variable $ip is in the program its defined it just shows up that uninitialised any help on this?

#!/usr/bin/perl -w use Regexp::Common qw/net/; use warnings; #use strict; use Regexp::Common qw/net/; use strict; use Cwd; my $mypath=getcwd(); my $mypath=$mypath."/sd"; my $ip; chdir $mypath; my @files = <*>; my $var=0; my $i = 0; my $traceroute; my $line; foreach (@files) { if (-f $_) { process ($_); } } sub process { my $file2 = $_[0]; open my $in, '<', $file2 or die $!; open my $out, '>', "$file2.log" or die $!; while (my $line = <$in>){ if($line =~ /^Traceroute: .* (\S+)/) { $traceroute = $1; #print "$traceroute\n"; $var++; #print "$traceroute\n"; } my ($ip) = $line =~ /(?: \d+ \s \s+) ($RE{net}{IPv4}) /msx +; print "$ip\n"; if($traceroute eq $ip){ print {$out} $ip if defined ; if($ip ne undef){ {$i++;} } } else { } } print {$out} "Number of traceroutes - $var\n"; print {$out} "Number of traceroutes reached destination - $i\n"; my $subs = $var-$i; print {$out} "Number of traceroutes that did not reaach destination ($ +subs)\n"; my $perc = ($i/$var)*100; print {$out} "Percentage of sucessful traceroutes ($perc%)\n"; # ... your remain code here }

Replies are listed 'Best First'.
Re: Reading Multiple files
by nemesdani (Friar) on Aug 07, 2012 at 11:47 UTC
    Pack your algorythm in a sub.
    Create a list with the names of the files you'd like to process.
    Create a loop (a foreach maybe) with which you invoke your sub on every file.

    I'm too lazy to be proud of being impatient.
      Here is sample:See if this can help you.
      opendir $dh, $dir_of_files or die "Couldn't open dir '$dir_of_files': +$!"; my @comparefiles= readdir $dh; closedir $dh; for each $file in @comparefiles { read_write_subroutine($file); } sub read_write_subroutine { put your whole code here which is currently you are using }

        Hoe to generate different file names for the output?

      Like you mean subroutine? But then what about the file names? Will need different file names for each of the file

        You can generate output file names dynamically. For example, my $input=$_[0]; my $output="./Result_of_processing_$input.txt";.
        More strict way: my $output = "Result_".$input.".txt";
        Sorry if my advice was wrong.
Re: Reading Multiple files
by 2teez (Vicar) on Aug 07, 2012 at 13:06 UTC

    If I may give you a head up. There are several ways to achieving your aim and this is one of them.

    • Using the module File::Find, you can transverse the whole of the directory ( or directories ), then
    • get each of the file, one after another, read through, using a while loop, within an open function, then do whatever you want!
    Please see an example below.
    use warnings; use strict; use File::Find qw(find); use File::Basename qw(basename); use Carp qw(croak); croak "Usage: <drectory_name>" unless defined $ARGV[0]; my $directory_name = $ARGV[0]; find( \&work_n_save, $directory_name ); # transverse the directory for + each file sub work_n_save { return if $_ eq '.' or $_ eq '..'; my $filename = $File::Find::name if !-d; ## get file name if not + directory $filename = basename($filename); ## get the file base na +me $filename =~ s/\..+$//; ## remove the file exte +ntion open my $fh_new, '>', $filename . "_new.txt" or croak "can't open +file: $!"; open my $fh, '<', $_ or croak "can't open file: $!"; while ( defined( my $line = <$fh> ) ) { chomp $line; ## do whatever you want print {$fh_new} $line, $/; } }
    NOTE: That the script above will save the new file generated within the same directory, where the original files are.
    If you don't want that you might have to create another dircetory and move your new file there!( easy too! )
    Try/Test this on any of directory you have and see what you get, then re-write to what you want!

    Check perldoc File::Find for detail info.
    Hope it helps.

      I am not an expert in perl but the code that i have written already defines a file name so what should i do with that? Sorry I did not understand your code completely I am still doing it. Any help on this?

        ..the code that i have written already defines a file name..

        The script I wrote, was on the premises that you want to write your selected "data", from each of the file, to a new file each.
        So, if your intention, then is to use just one file, to get all the selected "data", from various files in the directory ( or directories ), since you said you already have a filename. Then, you might have to modify, your code a bit.
        However, I might be wrong here. Please, if I may clear thing out.
        How are you getting your new files?
        Are you writing, all your output to a single file?
        Or to a new file for EACH file you are reading from?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://985943]
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (9)
As of 2018-06-18 16:31 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (110 votes). Check out past polls.