Home > Archive > PERL Miscellaneous > February 2007 > Help with search and replace
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Help with search and replace
|
|
|
| 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. Gleixner 2007-02-23, 7:07 pm |
| 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
| |
|
| Thanks for the reply..how can i pass search & replace strings as
arguments to the script
| |
| Brian McCauley 2007-02-23, 7:07 pm |
| On Feb 23, 5:51 pm, "Deepu" <pradeep...@gmail.com> 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;
| |
| Jürgen Exner 2007-02-23, 7:07 pm |
| 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
| |
|
| > > 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
| |
| John W. Krahn 2007-02-23, 7:07 pm |
| Deepu wrote:
> 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
| |
|
| > 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__
>
| |
| J. Gleixner 2007-02-23, 7:07 pm |
| Deepu wrote:
Ahhh. who wrote this reply? Leave that in place.[color=darkred]
>
> 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ürgen Exner 2007-02-23, 10:04 pm |
| 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
| |
| Tad McClellan 2007-02-23, 10:04 pm |
| Deepu <pradeep.bg@gmail.com> 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
tadmc@augustmail.com Perl programming
Fort Worth, Texas
| |
| Tad McClellan 2007-02-23, 10:04 pm |
| Deepu <pradeep.bg@gmail.com> 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
tadmc@augustmail.com Perl programming
Fort Worth, Texas
| |
| John W. Krahn 2007-02-24, 4:07 am |
| Deepu wrote:
>
> 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
| |
| Ayaz Ahmed Khan 2007-02-24, 4:08 am |
| "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.
|
|
|
|
|