in reply to search and replace strings in different files in a directory

You've fallen for the basic readdir trap

Also, you're not using $^I correctly (you really don't want to use it anyway)

Make your life easier by using Path::Tiny, improve this program

#!/usr/bin/perl -- ## ## ## ## perltidy -olq -csc -csci=3 -cscl="sub : BEGIN END if " -otr -opr - +ce -nibc -i=4 -pt=0 "-nsak=*" ## perltidy -olq -csc -csci=10 -cscl="sub : BEGIN END if " -otr -opr +-ce -nibc -i=4 -pt=0 "-nsak=*" #!/usr/bin/perl -- use strict; use warnings; use Path::Tiny qw/ path /; use POSIX(); use autodie qw/ close /; Main( @ARGV ); exit( 0 ); sub Main { my $date = POSIX::strftime( '%Y-%m-%d', localtime ); my $bak = "$date.bak"; my @xml_files = path( $directory )->children( qr/\.xml$/ ); for my $file ( @xml_files ) { Diddle( $file, "$file-$bak" ); } } ## end sub Main sub Diddle { my( $in, $bak ) = @_; path( $in )->move( $bak ); my $infh = path( $bak )->openr_raw; my $outfh = path( $in )->openrw_raw; while( <$infh> ) { s{&}{&amp;}g; ## will match more than what you want fix it s{&amp;amp;}{&amp;}g; s{\s>\s}{&gt;}g; s{\s<\s}{&lt;}g; print $outfh $_; } close $infh; close $outfh; } ## end sub Diddle
  • Comment on Re: search and replace strings in different files in a directory (Path::Tiny)
  • Download Code

Replies are listed 'Best First'.
Re^2: search and replace strings in different files in a directory (Path::Tiny)
by PitifulProgrammer (Acolyte) on Aug 18, 2014 at 10:49 UTC
    Dear Anonymous Monk

    Sorry for not having replied earlier. I was working on something else. However, last week, I was asked to have a go at the script again.

    What has changed is that the directories and files should now be accessed individually.

    The idea was to have a text file containing the pathnames in a network folder.

    My issue and the reason for reopening the question is how to add the different pathnames from the text-file, which are stored in the array to the subroutine

    I am having some difficulties with the line containing 'directory', because none of the changes I made actually worked

    I figure the pathnames have to go in there.

    I've been getting the following error messages

    c:\dev>perl search_and_replace.pl Global symbol "$directory" requires explicit package name at search_an +d_replace.pl line 33. Execution of search_and_replace.pl aborted due to compilation errors.
    c:\dev>perl search_and_replace.pl Path::Tiny paths require defined, positive-length parts at search_and_ +replace.pl line 33
    c:\dev>perl search_and_replace.pl Variable "$path" is not imported at hornbach_mit_verz_suche.pl line 34 +. (Did you mean &path instead?) Global symbol "$path" requires explicit package name at search_and_rep +lace.pl line 34.
    c:\dev>perl search_and_replace.pl ': Filename too long at search_and_replace.pl line 34.
    I can explain some of the errors such as variable scope (I don't think I can just $path inside the sub), but the question remains how to get the pathnames into the sub, but I have not yet touched subroutines in detail yet.

    I am sorry for all these questions, this script has evolved in a way I could not have aniticipated and the guys at work are eager for a solution.

    Oh yes, before I forget, this is the latest version of the script

    use 5.014; use strict; use warnings; use File::Slurp qw(:all); use Path::Tiny qw/ path /; use POSIX(); use autodie qw/ close /; my $infile_paths = 'C:\temp\test_folder\paths.txt'; my @paths = read_file $infile_paths, { binmode => ':utf8' } or die $!; chomp(@paths); # say for @paths; foreach my $path (@paths){ Main($path), } Main( @ARGV ); exit( 0 ); sub Main { my $directory = ""; my $date = POSIX::strftime( '%Y-%m-%d', localtime ); my $bak = "$date.bak"; my @xml_files = path( @paths )->children( qr/\.xml$/ ); for my $file ( @xml_files ) { Replace( $file, "$file-$bak" ); } } ## end sub Main sub Replace { my( $in, $bak ) = @_; path( $in )->move( $bak ); my $infh = path( $bak )->openr_raw; my $outfh = path( $in )->openrw_raw; while( <$infh> ) { s{&}{&amp;}g; ## will match more than what you want fix it s{&amp;amp;}{&amp;}g; s{\s>\s}{&gt;}g; s{\s<\s}{&lt;}g; print $outfh $_; } close $infh; close $outfh; } ## end sub Replace

    Thank you all so much for going through the trouble and explaining stuff to beginner. You guys rock, keep it going! I wish I had more time to play with the code and read up on certain aspects.

    Thank you so much. Looking forward to your reply.

    Please let me know if you need additional information, I still need to get used describing my problems in detail

    Kind regards C.

        Thanks a mil for providing this code. I appreciate your help, but this complicates matters, I cannot make heads nor tails of this.

        It is a bit too cryptic for a beginner like me who has not yet grasped some basic concepts.

        Would you mind providing some explanatory sentences and establish a link to my recent problem?

        I might learn faster if provided with some practical examples

        I surely will have another go at your code and try to figure what you would like to teach me.

        Thanks a mil for taking the trouble explaining this matter.

        Kind regards

        C.