Help with search and replace

Discussion in 'Perl Misc' started by Deepu, Feb 23, 2007.

  1. Deepu

    Deepu Guest

    Hi All,

    I am trying to replace a word in a line with a different word.

    Example:

    File1:
    THIS IS AN ERROR TEST
    THIS IS A TEST
    THIS IS NOT A TEST

    I need to go through this file and check for ERROR in any line and
    replace with FAIL.

    Please help me on this.

    Code:

    #!/usr/local/bin/perl

    $testFile = "File1";

    open (FH, "$testFile") || die;

    while (<FH>) {
    chomp;
    if ($_ =~ /ERROR/) {
    print "$_\n"; ## I get the line with ERROR here
    }
    }

    Thanks
     
    Deepu, Feb 23, 2007
    #1
    1. Advertising

  2. Deepu

    J. Gleixner Guest

    Deepu wrote:
    > Hi All,
    >
    > I am trying to replace a word in a line with a different word.
    >
    > Example:
    >
    > File1:
    > THIS IS AN ERROR TEST
    > THIS IS A TEST
    > THIS IS NOT A TEST
    >
    > I need to go through this file and check for ERROR in any line and
    > replace with FAIL.
    >
    > Please help me on this.
    >
    > Code:
    >
    > #!/usr/local/bin/perl
    >
    > $testFile = "File1";
    >
    > open (FH, "$testFile") || die;

    Include why.
    open( my $fh, '<', $testFile ) or die "Can't open $testFile: $!";

    >
    > while (<FH>) {

    while( <$fh> ) {
    > chomp;

    That's probably not needed.
    > if ($_ =~ /ERROR/) {

    if( /ERROR/ ) {
    > print "$_\n"; ## I get the line with ERROR here

    s/ERROR/FAIL/g;
    print;
    > }
    > }

    close $fh;

    That will print the line, that used to contain ERROR,
    and now contains FAIL, to STDOUT.

    If you want to change it in the file.

    perldoc -q 'How do I change one line'

    How do I change one line in a file/delete a line in a file/insert a
    line in the middle of a file/append to the beginning of a file?

    Use the Tie::File module, which is included in the standard
    distribution since Perl 5.8.0.

    For information on how to use that module:

    perldoc Tie::File
     
    J. Gleixner, Feb 23, 2007
    #2
    1. Advertising

  3. Deepu

    Deepu Guest

    Thanks for the reply..how can i pass search & replace strings as
    arguments to the script
     
    Deepu, Feb 23, 2007
    #3
  4. On Feb 23, 5:51 pm, "Deepu" <> wrote without
    adequate context:

    [ please don't do that ]

    > Thanks for the reply..how can i pass search & replace strings as
    > arguments to the script


    Command line arguments to a Perl script are placed in the special
    array variable @ARGV.

    Be aware, however, that in the solution given earlier in this thread
    'ERROR' is being treated as a regular expression _not_ a plain string.

    s/\Q$ARGV[0]/$ARGV[1]/g;

    Or slightly more long winded but maybe clearer:

    # Ouside the loop
    my ($search,$replace) = @ARGV;

    # Inside the loop
    s/\Q$search/$replace/g;
     
    Brian McCauley, Feb 23, 2007
    #4
  5. Deepu wrote:
    > Thanks for the reply..


    What reply? I don't see any. What are you talking about?

    > how can i pass search & replace strings as
    > arguments to the script


    The same way as you would pass any other argument to any other program: you
    just type them on the command line after the command or script name.

    jue
     
    Jürgen Exner, Feb 23, 2007
    #5
  6. Deepu

    Deepu Guest

    > > Thanks for the reply..
    > What reply? I don't see any. What are you talking about?
    >

    I will try to post the message correctly in future..sorry about that

    I tried the code as given below:

    #!/usr/local/bin/perl

    my ($search,$replace) = @ARGV;

    my $baseDir = "/user/bin";

    opendir (DIR, $baseDir) || die "Can't open $baseDir - $!\n";

    # -- Perform the operation for each DIR
    foreach my $simdir (readdir DIR) {

    # -- If it is a directory and ends with 1-6
    if (-d "$baseDir/$subdir" && $subdir =~ /(1|2|3|4|5|6)$/) {

    # -- If the directory has subdirectories do the following operation
    opendir (SUBDIR, "$baseDir"."/$subdir" ) || die "Can't open
    $subdir - $!\n";

    # -- Perform the operation for each of the sub-subdirectory
    while ( my $subsubdir = readdir (SUBDIR)) {
    if (-d "$baseDir/$subdir/$subsubdir" && $subsubdir =~ /(\d)$/) {
    chomp $subsubdir;
    if (-e "$baseDir/$subdir/$subsubdir/run.log")
    {
    my $temp = "$baseDir"."/$subdir/$subsubdir/File.log";
    open (my $fh,'>',$temp) || die "Can't open $temp -$!\n";

    while (<$fh>){
    s/$search/$replace/g;
    }
    close ($fh);
    }
    }
    }
    close SUBDIR;

    # -- Else perform the same operation as before without the sub-
    subdirectory
    if (-e "$baseDir/$subdir/run.log")
    {
    my $temp = "$baseDir"."/$subdir/File.log";
    open (my $fh,'>',$temp) || die "Can't open $temp -$!\n";

    while (<$fh>){
    s/$search/$replace/g;
    }
    close ($fh);
    }
    }
    }

    close DIR;


    But when i use this File.log becomes an empty file.

    Basically File.log is present in $baseDir/subdir/ or $baseDir/$subdir/
    $subsubdir

    Example:

    under /user/bin/ there are:

    DIR1 - File.log
    DIR2 - SUBDIR1 - File.log
    DIR3 - SUBDIR1 - File.log
    - SUBDIR2 - File.log
    DIR4 - SUBDIR1 - File.log

    File.log has:
    THIS IS AN ERROR TEST
    THIS IS A TEST
    THIS IS NOT A TEST
    THIS IS AN ERROR

    I need to replace ERROR with FAIL or sometimes someother word so am
    trying to pass as arguments
     
    Deepu, Feb 23, 2007
    #6
  7. Deepu wrote:
    >>>Thanks for the reply..

    >>What reply? I don't see any. What are you talking about?
    >>

    > I will try to post the message correctly in future..sorry about that
    >
    > I tried the code as given below:
    >
    > #!/usr/local/bin/perl


    Missing:

    use warnings;
    use strict;

    > my ($search,$replace) = @ARGV;
    >
    > my $baseDir = "/user/bin";
    >
    > opendir (DIR, $baseDir) || die "Can't open $baseDir - $!\n";
    >
    > # -- Perform the operation for each DIR
    > foreach my $simdir (readdir DIR) {

    ^^^^^^^
    You variable should be named $subdir, at least that is the name you are using
    everywhere else in this program.


    > # -- If it is a directory and ends with 1-6
    > if (-d "$baseDir/$subdir" && $subdir =~ /(1|2|3|4|5|6)$/) {


    You don't need capturing parentheses and a character class would be more
    efficient:

    if (-d "$baseDir/$subdir" && $subdir =~ /[123456]$/) {


    > # -- If the directory has subdirectories do the following operation
    > opendir (SUBDIR, "$baseDir"."/$subdir" ) || die "Can't open
    > $subdir - $!\n";
    >
    > # -- Perform the operation for each of the sub-subdirectory
    > while ( my $subsubdir = readdir (SUBDIR)) {
    > if (-d "$baseDir/$subdir/$subsubdir" && $subsubdir =~ /(\d)$/) {
    > chomp $subsubdir;
    > if (-e "$baseDir/$subdir/$subsubdir/run.log")
    > {
    > my $temp = "$baseDir"."/$subdir/$subsubdir/File.log";
    > open (my $fh,'>',$temp) || die "Can't open $temp -$!\n";
    >
    > while (<$fh>){


    You are trying to READ from a file opened WRITEONLY. This will not work.


    > s/$search/$replace/g;


    You are trying to modify the line in memory however this has no effect on the
    file itself because you are not storing the line antwhere.


    > }
    > close ($fh);
    > }
    > }
    > }
    > close SUBDIR;
    >
    > # -- Else perform the same operation as before without the sub-
    > subdirectory
    > if (-e "$baseDir/$subdir/run.log")
    > {
    > my $temp = "$baseDir"."/$subdir/File.log";
    > open (my $fh,'>',$temp) || die "Can't open $temp -$!\n";
    >
    > while (<$fh>){
    > s/$search/$replace/g;
    > }
    > close ($fh);
    > }
    > }
    > }
    >
    > close DIR;
    >
    >
    > But when i use this File.log becomes an empty file.
    >
    > Basically File.log is present in $baseDir/subdir/ or $baseDir/$subdir/
    > $subsubdir
    >
    > Example:
    >
    > under /user/bin/ there are:
    >
    > DIR1 - File.log
    > DIR2 - SUBDIR1 - File.log
    > DIR3 - SUBDIR1 - File.log
    > - SUBDIR2 - File.log
    > DIR4 - SUBDIR1 - File.log
    >
    > File.log has:
    > THIS IS AN ERROR TEST
    > THIS IS A TEST
    > THIS IS NOT A TEST
    > THIS IS AN ERROR
    >
    > I need to replace ERROR with FAIL or sometimes someother word so am
    > trying to pass as arguments


    Something like this should work (UNTESTED):

    #!/usr/local/bin/perl
    use warnings;
    use strict;
    use File::Basename;

    my ( $search, $replace ) = @ARGV;

    my @files = (
    glob( "/user/bin/*/run.log" ),
    glob( "/user/bin/*[123456]/*/run.log" ),
    );

    for my $file ( @files ) {
    my $new = dirname( $file ) . '/File.log';
    open my $in, '<', $file or die "Cannot open '$file' $!";
    open my $out, '>', $new or die "Cannot open '$new' $!";
    while ( <$in> ) {
    s/\Q$search\E/$replace/g;
    print $out;
    }
    }

    __END__





    John
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
     
    John W. Krahn, Feb 23, 2007
    #7
  8. Deepu

    Deepu Guest

    > Something like this should work (UNTESTED):
    >
    > #!/usr/local/bin/perl
    > use warnings;
    > use strict;
    > use File::Basename;
    >
    > my ( $search, $replace ) = @ARGV;
    >
    > my @files = (
    > glob( "/user/bin/*/run.log" ),
    > glob( "/user/bin/*[123456]/*/run.log" ),
    > );
    >
    > for my $file ( @files ) {
    > my $new = dirname( $file ) . '/File.log';
    > open my $in, '<', $file or die "Cannot open '$file' $!";


    How can i try to read and write to the same file?

    > open my $out, '>', $new or die "Cannot open '$new' $!";
    > while ( <$in> ) {
    > s/\Q$search\E/$replace/g;
    > print $out;
    > }
    > }
    >
    > __END__
    >
     
    Deepu, Feb 23, 2007
    #8
  9. Deepu

    J. Gleixner Guest

    Deepu wrote:
    >> Something like this should work (UNTESTED):

    Ahhh. who wrote this reply? Leave that in place.
    >>
    >> #!/usr/local/bin/perl
    >> use warnings;
    >> use strict;
    >> use File::Basename;
    >>
    >> my ( $search, $replace ) = @ARGV;
    >>
    >> my @files = (
    >> glob( "/user/bin/*/run.log" ),
    >> glob( "/user/bin/*[123456]/*/run.log" ),
    >> );
    >>
    >> for my $file ( @files ) {
    >> my $new = dirname( $file ) . '/File.log';
    >> open my $in, '<', $file or die "Cannot open '$file' $!";

    >
    > How can i try to read and write to the same file?


    Tie::File

    or write to the new file and rename it to the old.

    perldoc -f rename

    or use File::Copy or possibly something on
    the command line like:

    perl -pi -e 's/search/replace/g' /user/bin/*/run.log
    /user/bin/*[123456]/*/run.log

    or many more...

    Be sure to use a test directory and files, before you
    start trashing actual files.

    You can find many examples on-line. Give that a try
    or try to figure it out by reading the various FAQs,
    before simply replying with another question.
     
    J. Gleixner, Feb 23, 2007
    #9
  10. Deepu wrote:
    > my $temp = "$baseDir"."/$subdir/$subsubdir/File.log";
    > open (my $fh,'>',$temp) || die "Can't open $temp -$!\n";


    Ok, you are opening the file

    > while (<$fh>){


    You are reading each line in the file into $_

    > s/$search/$replace/g;


    You are replacing something in $_ with something else

    > }


    And then throwing it away

    > close ($fh);


    > But when i use this File.log becomes an empty file.


    Well, you never ever write anything anywhere.

    jue

    jue
     
    Jürgen Exner, Feb 24, 2007
    #10
  11. Deepu <> wrote:

    > How can i try to read and write to the same file?



    You can try any way that you want to.

    Very few of them will work though.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Feb 24, 2007
    #11
  12. Deepu <> wrote:

    > while ( my $subsubdir = readdir (SUBDIR)) {
    > if (-d "$baseDir/$subdir/$subsubdir" && $subsubdir =~ /(\d)$/) {
    > chomp $subsubdir;



    Do you really have directories whose names end with a newline?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Feb 24, 2007
    #12
  13. Deepu wrote:
    >>Something like this should work (UNTESTED):
    >>
    >>#!/usr/local/bin/perl
    >>use warnings;
    >>use strict;
    >>use File::Basename;
    >>
    >>my ( $search, $replace ) = @ARGV;
    >>
    >>my @files = (
    >> glob( "/user/bin/*/run.log" ),
    >> glob( "/user/bin/*[123456]/*/run.log" ),
    >> );
    >>
    >>for my $file ( @files ) {
    >> my $new = dirname( $file ) . '/File.log';
    >> open my $in, '<', $file or die "Cannot open '$file' $!";

    >
    > How can i try to read and write to the same file?


    Something like this should work (UNTESTED):

    #!/usr/local/bin/perl
    use warnings;
    use strict;

    my ( $search, $replace ) = @ARGV;

    @ARGV = (
    glob( "/user/bin/*[0-9]/run.log" ),
    glob( "/user/bin/*[1-6]/*[0-9]/run.log" ),
    );

    $^I = '';

    while ( <> ) {
    s/\Q$search\E/$replace/g;
    print;
    }

    __END__




    John
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
     
    John W. Krahn, Feb 24, 2007
    #13
  14. "Deepu" typed:

    > Hi All,
    > I am trying to replace a word in a line with a different word.
    > I need to go through this file and check for ERROR in any line and
    > replace with FAIL.


    A one-liner would do:

    $ perl -p -i -e 's/\bERROR\b/FAIL/g' file

    --
    Ayaz Ahmed Khan

    A witty saying proves nothing, but saying something pointless gets
    people's attention.
     
    Ayaz Ahmed Khan, Feb 24, 2007
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. techie2go
    Replies:
    3
    Views:
    275
    techie2go
    Sep 10, 2006
  2. Schif Schaf
    Replies:
    12
    Views:
    1,300
    Anthra Norell
    Feb 8, 2010
  3. Abby Lee
    Replies:
    5
    Views:
    443
    Abby Lee
    Aug 2, 2004
  4. Prasad S
    Replies:
    2
    Views:
    245
    Dr John Stockton
    Aug 27, 2004
  5. Ray Muforosky

    string substitution help (search and replace)

    Ray Muforosky, Mar 9, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    132
Loading...

Share This Page