bit5nip3r has asked for the wisdom of the Perl Monks concerning the following question:

Does anyone know of a good perl based robocopy log filer parser, or what kinds of building blocks are required to parse a robocopy log file?

What I'm looking to do is to pull out all new file entries, and to have the new directory entry that appears just above each new file entry placed next to it's corresponding file

Replies are listed 'Best First'.
Re: Robocopy log parsing
by bit5nip3r (Initiate) on May 28, 2012 at 15:17 UTC

    I feel like I'm almost there:

    use warnings; use strict; my $filename = $ARGV[0]; open(INFILE, "<", $filename) or die "Cannot open $ARGV[0]"; my(@fcont) = <INFILE>; $dir =~ m/[a-z]:\\.*?\n/g; foreach $line (@fcont) { if ($line =~ m/(New File|New Dir)\s+([0-9]+|[0-9].[0-9]\s[a-z]?)\s ++(.*?\n)/g) { print join("|",$ARGV[0],$1,$dir,$2,$3); } } close( INFILE );

    but of course it tells me $line and $dir requires explict package name. What am I mising? This will pull out all entries that are New Dir or New File, but I was hoping to bring down my New Dir match so that each New File had its correpondinf directory

      What am I mising?
      You are missing my before $line after foreach. You should also declare $dir, but I do not see where this variable gets its value.

        I wanted $dir to get its value from extracting text from the New Dir entry. For each new Dir there will be a x:\....\ string of text to denote a folder path, which for each line where there is New Dir match it assigns the value found to $dir, then for each corresponding line the print join prints the $dir value. Well that was the idea in theory. If I remove the $dir from the print join statement, it works. Ok so $line fixed. but still having probs with $dir. Does the $dir =~ not declare it as an assignment?

Re: Robocopy log parsing
by BrowserUk (Patriarch) on May 29, 2012 at 09:44 UTC

    You are making life hard for yourself. Why not just use the robocopy option to include full pathnames in the logfile?

    /FP :: include Full Pathname of files in the output.

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

      Don't have that option. I'm not the creator of these logs files.

        I think you want something like that:

        use warnings; use strict; my $filename = $ARGV[0]; #$filename = 'robocopy_log.txt'; open my $hin, '<', $filename or die "Cannot open file /$filename/"; my @fcont = <$hin>; my ( $dir, $txt, $nbytes, $file_found, $sav_dir, $sav_file ); foreach my $line (@fcont) { if ( $line =~ /New File|New Dir/ ) { ($dir) = $line =~ /New Dir\s+(?:[0-9]+|[0-9]+?\.[0-9]+? +\s[a-z])\s(.*)/; ($file_found) = $line =~ /New File\s+(?:[0-9]+|[0-9]+?\.[0-9]+ +?\s[a-z])\s(.*?)\s+?/; ( $txt, $nbytes ) = $line =~ /(New File|New Dir)\s+([0-9]+|[0- +9]+?\.[0-9]+?\s[a-z])\s.*/; $sav_dir = $dir if $dir; $sav_file = $file_found if $file_found; $sav_dir = !defined $sav_dir ? q{} : $sav_dir; $sav_file = !defined $sav_file ? q{} : $sav_file; print join( "\t\t", $txt, $sav_dir, $nbytes, $sav_file ) . "\n +"; } } close $hin;

        Also look at this example, how to avoid $1, $2, ... matching parameters, you can directly assing the result to a list of variables

        You also can try to put the three assignments in ony line, this is left as an exercise ;-)