Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Re: Search & Replace in subdirectory files

by bassplayer (Monsignor)
on Apr 23, 2004 at 14:28 UTC ( #347634=note: print w/replies, xml ) Need Help??

in reply to Search & Replace in subdirectory files

# perl -p -i.bak -e 's/bilbo/frodo/g' *

This (at command prompt) will change all instances of 'bilbo' to 'frodo' in all files in the directory, creating a backup called filename.bak.

Not really sure how to make it recurse subdirectories other than adding /* on the end for each level needed:

# perl -p -i.bak -e 's/bilbo/frodo/g' */*

Be careful...


Replies are listed 'Best First'.
Re: Re: Search & Replace in subdirectory files
by borisz (Canon) on Apr 23, 2004 at 14:56 UTC
    Not really sure how to make it recurse subdirectories other than adding /* on the end for each level needed:
     # perl -p -i.bak -e 's/bilbo/frodo/g' */*
    Then we are back at File::Find.
    #!/usr/bin/perl use File::Find; my @dirs = @ARGV; @ARGV = (); File::Find::find( { wanted => sub { push @ARGV, $File::Find::name if -f } }, @dirs ); $^I = '.bak'; local $_; while ( defined( $_ = <ARGV> ) ) { s/bilbo/frodo/g; print; }
      Not necessarily. File::Find is the solution I would use if the script is to be run regularly. However, with a one time change, I would still use the command line. It's just so easy. If I have five levels to recurse, I run it five times. Granted, if there is an unknown level of subdiectories, then a folder could be missed, but this one-liner has served me well and I just thought I'd share it. TIMTOWTDI, right? I guess I should have explained that in previous reply.


Re: Re: Search & Replace in subdirectory files
by Rina (Initiate) on Apr 23, 2004 at 15:23 UTC
    Thank you for your replies so far; I've been reading the file::find references you gave me, going through the book, and testing your suggestions.

    However, I will be more specific because I haven't gotten the result I need yet. There are some 350+ folders & subfolders so I need this to recurse.

    The line where that substring exists looks like this:

    //$Log: \\Server\Dir1\subDir1\subDir2\filename.cpp $

    I want to search every file to replace every instance of "$Log:" with "$History:".

    Either nothing happens, or the entire line before "filename.cpp $" disappears when I do one of the following:

    $InputArray =~ s/Log/History/gi;

    $InputArray =~ s/\$Log/\$History/gi;

    $InputArray =~ s/\$Log\:/\$History\:/gi;
      I can not see, how you lose a line, that is a error somewhere else. To replace '$Log:' with '$History:' this is enough.
      $input =~ s/\$Log:/\$History:/gi;
      Note that $InputArray is _not_ a array.
        "perl -p -i.bak -e 's/\$Log/\$History/gi' * " at the command line only creates filename.ext.bak, nothing else.

        Boris, you're right, but I only showed a snippet of my code. I had something else being sent to the output file instead of $InputArray.

        Below is the full script, which works on a single file. Actually, I don't want to create a new file, I just want to modify the existing file, but this is what I know to do so far. I'm thinking there's a way to use "readdir" to provide the list of files so that the first line would read something like " Open (InputFile, $FileArray)".

        Thanks a LOT!!!

        open( InputFile, "FirstFile.txt" );
        open( OutputFile, ">SecondFile.txt" );
        @InputArrays = <InputFile>;

        foreach $InputArray ( @InputArrays)
        $InputArray =~ s/\$Log/\$History/gi;
        chomp ($InputArray);
        @myColumns = split(/\\/, $InputArray);
        print (OutputFile "\n$InputArray");

        close( InputFile );
        close( OutputFile );

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://347634]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2017-10-22 00:11 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (271 votes). Check out past polls.