Help with search and replace

D

Deepu

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
 
J

J. Gleixner

Deepu said:
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( said:
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
 
D

Deepu

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

Brian McCauley

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;
 
J

Jürgen Exner

Deepu said:
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
 
D

Deepu

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
 
J

John W. Krahn

Deepu said:
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
 
D

Deepu

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?
 
J

J. Gleixner

Deepu said:
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

Jürgen Exner

Deepu said:
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
 
T

Tad McClellan

Deepu said:
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?
 
J

John W. Krahn

Deepu said:
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
 
A

Ayaz Ahmed Khan

"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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top