Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

process a file and reading a line and passing the values to another sub function

by Vijay81 (Acolyte)
on Dec 12, 2012 at 15:41 UTC ( #1008518=perlquestion: print w/ replies, xml ) Need Help??
Vijay81 has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

Am trying to read directory/subdirectories and for files from a path recursively. Once file found in any directory, reading file content(usually just 1 line in a file) and substituting space with comma from the line. then I need to pass the values to another sub functions.

Problem : 1. line number 35 doesn't seems to be working. when i try to print $line, it doesn't show anything/value. 2. Need to pass @columns/@filenames/@dir_names to the sub function(&write_output) called in line number 46.

Can someone tell me where am doing wrong and help me out

I need to know is there any tool/utlity for Windows XP where in which in can run the perl script line by line debugging mode so, that i can see what's happen to the variables during run time.

Many Thanks...
#! /usr/bin/perl use warnings; use strict; use File::Find; use File::Basename; my $base_dir = 'C:\Perl\TestData'; my (@columns,@dirs,@buf,@dir_names,@filenames); my ($dir,$file,$resultxmlfile,$line,$fh); $line=''; sub process_files { print "dive into: $_[0]\n"; opendir DIR, $_[0] or die "Could not open directory"; print $_[0]; print "\n"; @dirs = readdir DIR; closedir DIR; foreach $file (@dirs) { if ($file =~ /\.{1,2}/) {next } print "processing: $file\n"; if ( -d "$_[0]/$file" ) { process_files ("$_[0]/$file"); push(@dir_names, basename($file)); print @dir_names; print "\n"; foreach my $file (@dirs){ print $file; next if $file eq '.' or $file eq '..'; print "\n"; open (FILE, "<", $file) or die "Could not open file -- $_[0] +/$file"; @buf = <FILE>; foreach $line (@buf) { $line = <FILE>; # this line doesn't work. don't know w +hat's wrong here.. $line=~ s/ /,/g; print $line; push(@columns,$line); print @columns; print "\n"; $file =~ s/.*\///; $file =~ s/\.[^.]+$//; push(@filenames, $file); print @filenames; } &write_output; # need to pass @columns/@filenames/@dir +_names values to this function close FILE; } } } } process_files $base_dir;

Comment on process a file and reading a line and passing the values to another sub function
Download Code
Replies are listed 'Best First'.
Re: process a file and reading a line and passing the values to another sub function
by LanX (Canon) on Dec 12, 2012 at 16:28 UTC
    please try to condense code to the relevant parts or mark them better.

    I really started counting the lines till 35 before I saw your comment.

    something like:

    $line = <FILE>; # <---------- 35 # this line doesn't work. don't know what's wrong here..

    is easier to find.

    anyway, you did it twice:

    @buf = <FILE>; # you reading all lines of FILE i +nto @buf foreach $line (@buf) { # OK! (well, "my $line" would be +better) $line = <FILE>; # but now reading again a single +line !?! # which is undef after EOF

    please less cargo cult programming!

    Don't c&p different approaches from other snippets, better try to understand what's happening.

    Cheers Rolf

Re: process a file and reading a line and passing the values to another sub function
by marto (Bishop) on Dec 12, 2012 at 15:48 UTC

    "I need to know is there any tool/utlity for Windows XP where in which in can run the perl script line by line debugging mode so, that i can see what's happen to the variables during run time."

    Perl has a debugger, learn how to use it here: perldebtut.

Re: process a file and reading a line and passing the values to another sub function
by 2teez (Priest) on Dec 12, 2012 at 16:43 UTC

    Hi Vijay8l,
    Am trying to read directory/subdirectories and for files from a path recursively

    Why not use File::Find instead of doing all the jobs yourself.

    ..reading file content(usually just 1 line in a file) and substituting space with comma from the line.
    Are you trying to create a Comma-separated values files? If yes then see Text::CSV.

    Just to give a head up, using File::Find and substitution function, I did something very close to what you wanted.

    #!/usr/bin/perl use warnings; use strict; use File::Find; my $base_dir = '...'; # put in your base directory find( \&wanted, $base_dir ); sub wanted { return if $_ eq '.' or $_ eq '..'; if (-d) { print " >>> dive into: $_\n" if -d; } else { readout_file($_); ## call subroutine readout_file } } sub readout_file { my ($filename) = @_; open my $fh, '<', $filename or die "can't open file:$!"; while (<$fh>) { chomp; s/ /,/; ## OR s/ /,/g; if you want print $_, $/; ## OR any other subroutine you want } }

    Update:
    Seriously, Please look into Text::CSV if csv files are intended.
    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: process a file and reading a line and passing the values to another sub function
by blue_cowdawg (Monsignor) on Dec 12, 2012 at 18:38 UTC

    As mentioned elsewhere you can use find2perl to create a skeleton program for you that does the job very well. But here's a piece of code I have laying around that may or may not work for what you want to do.

    #!/usr/bin/perl -w ###################################################################### +## use strict; my $start="/some/path/to/some/where"; crawl($start); exit(0); sub crawl { my $dir = shift; opendir(my $dh,$dir) or die "$dir: $!"; while (my $entry=readdir($dh)){ next if ($entry eq '.') || ($entry eq '..'); printf "%s\n",$entry; if ( -d $entry ) { crawl($dir . "/" . $entry); } } closedir($dh); }
    Now... them's the basics...

    Embelish the output or actions as you need. For instance if I were to use this "real time" I'd add an indentation element or even ASCII art elements to it to make the output more useful.

    HTH


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: process a file and reading a line and passing the values to another sub function
by Vijay81 (Acolyte) on Dec 13, 2012 at 20:46 UTC

    ok, finally i found out that we can use split function to put the comma seperated line into array element.

    </codesub readout_file { my ($filename) = @_; my (@linecolumns); open my $fh, '<', $filename or die "can't open file:$!"; while (<$fh>) { chomp; ~s/ /,/g; ## OR s/ /,/g; if you want print $_, $/; @linecolumns = split(',',$_); #print $_, $/; ## OR any other subroutine you want print $linecolumns[0],$/; print $filename, $/; } }
Re: process a file and reading a line and passing the values to another sub function
by Vijay81 (Acolyte) on Dec 13, 2012 at 14:27 UTC

    Thanks Everyone. @2Teez, what you suggested is what i was looking but now, when put $line conent to some array after doing csv(somma seperated), am not able to get any values to $line or @linecolumns. Can you please suggest help me on how to get the $line value into some array so, that i can pass that array element/value to another sub function.

    #!/usr/bin/perl use warnings; use strict; use File::Find; my $base_dir = 'C:\\TestData'; # put in your base directory my ($dirname,$filename,$line); my (@linecolumns); find( \&wanted, $base_dir ); sub wanted { return if $_ eq '.' or $_ eq '..'; if (-d) { print " >>> dive into: $_\n" if -d; $dirname = $_; } else { readout_file($_); ## call subroutine readout_file } } sub readout_file { my ($filename) = @_; open my $fh, '<', $filename or die "can't open file:$!"; while ($line=<$fh>) { chomp; $line=~s/ /,/g; ## OR s/ /,/g; if you want print $line, $/; push(@linecolumns,$line); #print $_, $/; ## OR any other subroutine you want print $linecolumns[0], $/; print $filename, $/; #write_output($dirname,$filename,$linecolumns[0],$linecolumns[3]); ## +call subroutine to print std template in output file } }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1008518]
Approved by bitingduck
Front-paged by 2teez
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2015-07-30 04:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (269 votes), past polls