Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

array of hashes help

by rv799cv (Initiate)
on Apr 23, 2014 at 21:00 UTC ( [id://1083461]=perlquestion: print w/replies, xml ) Need Help??

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

Hello All,

Gabor Azabo re-directed me to this site and I hope someone can give me a guide and clue.

I have wrote a Perl script to update about 1200 files for searching and replacing.

I have used a array of hashes like my

@myHashArray = ( {toFind => '<Image Name="Logo"> <Source>Embedded</Sou +rce>', toReplace => '<Image Name="Logo"><Source>E +xternal</Source>' }); Then I use this statement to find and replace the file. $data =~ s/$_->{toFind}/$_->{toReplace}/g foreach (@myHashArray);

Everything is working great and I am creating a log file (name of files I have changed) but I like also to get the values I have changed in that document. I want to get the value of /$_->{toFind}/ and toReplace in a log file too. Currently my log file is something like:

01- FirstFile.xml

02- SecondFile.xml

But want to have something like

01- FirstFile.xml

a. Original line: <Image

Name="Logo"><Source>Embedded</Source>

b. Replace with: <Image Name="Logo"><Source>External</Source>

And so on...

Replies are listed 'Best First'.
Re: array of hashes help
by rjt (Curate) on Apr 23, 2014 at 21:13 UTC

    If I understand you correctly, you just want the contents of toFind and the contents of toReplace in the same log file, right? Would this work?

     $data =~ s/$_->{toFind}/Original line: $_->{toFind}\n Replace with: $_->{toReplace}\n/g foreach (@myHashArray);

    But I confess I really don't know what you're doing or why you're doing it. Perhaps most importantly, you seem to make a distinction between "about 1200 files", and "a log file", but the code you have shown has no evidence of that (or, indeed, output of any kind). The $data =~ ... bit looks like it might be the original text replacement, but then where is the log file? Or is there another explanation entirely?

    use strict; use warnings; omitted for brevity.

      thanks you so much for your input and quick response

      Here I go through a loop of files and after reading files into $data I find and replace them using the write_file

      $data =~ s/$_->{toFind}/$_->{toReplace}/g foreach (@myHashArray); write_file($File::Find::name, $data); print LOGFILE "$counter $File::Find::name\n"; print LOGFILE "\t Original line: HERE WOULD BE MY ORIGINAL + LINE\n"; print LOGFILE "\t Replaced Line: HERE WOULD BE THE NEW LIN +E\n"; print "$counter $File::Find::name\n";

        Ok, that helps. If your files are indeed line-based (i.e., your patterns do not span multiple lines), then I suggest processing them line-by-line:

        use File::Slurp; my @myHashArray = ( { toFind => qr/(?i)foo/, toReplace => 'bar' } ); my $counter = 0; my $name = 'data_file'; # $File::Find::name for my $line (read_file('data_file', chomp => 1)) { $counter++; my $orig_line = $line; $line =~ s/$_->{toFind}/$_->{toReplace}/g for @myHashArray; next if $line eq $orig_line; print "LOG: $counter $name\n"; print "LOG: \t Original line: $orig_line\n"; print "LOG: \t Replaced line: $line\n"; }

        Here I've replaced LOGFILE with a LOG: prefix for ease of testing, and eliminated the reliance on File::Find for the same reason.

        With the following data_file:

        Foolius Caesar Footholomew Cubbins No changes here Just another barrage of text

        I get the following output:

        LOG: 1 data_file LOG: Original line: Foolius Caesar LOG: Replaced line: barlius Caesar LOG: 2 data_file LOG: Original line: Footholomew Cubbins LOG: Replaced line: bartholomew Cubbins

        Does that help?

        use strict; use warnings; omitted for brevity.
Re: array of hashes help
by Fessenden (Initiate) on Apr 23, 2014 at 23:23 UTC
    Could you just use regex variable capture? Enclose the toFind and toReplace with parentheses, like:
    $data =~ s/($_->{toFind})/($_->{toReplace})/g foreach (@myHashArray);
    And access them to print out to your log with $1 and $2?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1083461]
Approved by rnewsham
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-19 23:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found