Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

search and replace 2

Status
Not open for further replies.

dietmarp

Programmer
Joined
Dec 27, 2001
Messages
53
Location
US
Hi, I run into following problem. I got a config file i.e.
....
#FileName=fsmon.txt
#config file
managed_target=AIX
"*" P M 95 F 98
"/" P M 80 F 85 0
"/tmp" P M 90 F 95 0
"/var" P M 90 F 95 0
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 97 F 99 0
"/*/orabase" P M 90 F 95 0
"/*/orabase/data/????/dat*" P M 100 F 100 0

managed_target=SAP
"/oracle/stage*" P M 100 F 100 0
"/oracle/???/orig*" P M 100 F 100 0
"/oracle/???/mirr*" P M 100 F 100 0

.....
on 100 aix boxes. I need to remove all lines belonging to managed_target=ORA and insert new ones i.e.

"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0


to have this block of information identical on all systems and not touch the other lines. On every box the lines could be different.

Any suggestions
- Dietmar
 
I think you need to explain this better. There is little relationship between the lines in the file and the lines you want to substitute them with. Do you just want to sub in those four lines you posted regardless of what's in the original file?
 
ok - the file to be changed contains different sections.
All sections start with
managed_target=?????? followed by one or more lines. Comments in this file always start with # .
In this case I need to find the section
managed_target=ORA, and replace all lines belonging to this section.

i.e.
old file ......
#FileName=fsmon.txt
#config file
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 97 F 99 0
"/*/orabase" P M 90 F 95 0
"/*/orabase/data/????/dat*" P M 100 F 100 0

managed_target=SAP
"/oracle/stage*" P M 100 F 100 0

new file ..............
#FileName=fsmon.txt
#config file
#FileName=fsmon.txt
#config file
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

managed_target=SAP
"/oracle/stage*" P M 100 F 100 0
........
The sections are usually seperated by a blank line, but there are exceptions.

 
How big are these files? kilobytes, megabytes, gigiabytes? Hundreds of lines, thousands, millions?

I'm thinking it might be easy to read the whole file into a scalar then use substitution to replace the lines, but if the file is too big this might not be practical. A few hundered lines per file would be no problem, even a few thousand lines should be no big deal.
 
something like this could work if the file isn't too big:

Code:
my $sub = qq~managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

~;

my $file = do {local $/; <DATA>};

$file =~ s/managed_target=ORA.+\n\s*\n/$sub/s;

print $file;

__DATA__
#FileName=fsmon.txt
#config file
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 97 F 99 0
"/*/orabase" P M 90 F 95 0
"/*/orabase/data/????/dat*" P M 100 F 100 0

managed_target=SAP
"/oracle/stage*" P M 100 F 100 0

the \s* is the regexp just in case there are any spaces on the blank lines, if not it can be removed.
 
the file is not very big - not more than a hundred lines.
 
OK, then backup your current files, and give the code I posted a try.

Code:
my $sub = qq~managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

~;

open(FH, 'thefile.txt') or die "$!";
my $file = do {local $/; <FH>};
close FH;
$file =~ s/managed_target=ORA.+\n\s*\n/$sub/s;
open(FH, '>thefile.txt') or die "$!";
print FH $file;
close FH;
 
ok - the substitution works generally, but all sections below the managed_tartet=ORA are deleted. But they are still needed. Only the managed_tartet=ORA section must be replaced.
----------------------------------------

#!/usr/bin/perl -w

use warnings;


my $sub = qq~managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

~;

open(FH, 'thefile.txt') or die "$!";
my $file = do {local $/; <FH>};
close FH;
$file =~ s/managed_target=ORA.+\n\s*\n/$sub/s;
open(FH, '>thefile.txt') or die "$!";
print FH $file;
close FH;

####################END###################

__thefile.txt__before
#FileName=fsmon.txt
#config file
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 97 F 99 0
"/*/orabase" P M 90 F 95 0
"/*/orabase/data/????/dat*" P M 100 F 100 0

managed_target=SAP
"/oracle/stage*" P M 100 F 100 0

-----------------------------------------

__thefile.txt__after_bad
#FileName=fsmon.txt
#config file
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

-----------------------------------------

__thefile.txt__after_good
#FileName=fsmon.txt
#config file
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

managed_target=SAP
"/oracle/stage*" P M 100 F 100 0
 
ok - I'm looking for a different approach. I do a "next if" to skip reading the lines containig "managed_target=ORA" and "orabase". I print the required lines to the end of the new file.

But possibly there could be lines in other sections containing the string orabase which must remain.

A better solution would be to look for the managed_target=ORA and then skip writing to new file until a new section starts (or EOF). Any suggestions. Many thanks for the help so far. Here's the code.
Code:
#!/usr/bin/perl -w
use strict;
use warnings;
###### variables#######
my $filename = "thefile.txt";
my $newfile = "thefilenew.txt";
my $sub = qq~managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0
~;
##### start processing file ########
open(FILEREAD, "< $filename");
open(FILEWRITE, "> $newfile");
while (<FILEREAD>){
    next if /managed_target=ORA/;
	next if /orabase/;
	print FILEWRITE;
}
print FILEWRITE $sub;
close FILEWRITE;
close FILEREAD;
####################END###################
 
how is this?

Code:
[b]#!/usr/bin/perl[/b]

$new_ORA = <<HERE;
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

HERE

while (<DATA>) {
  if (/^managed_target=ORA$/) {
    print;
    $ora_flag = 1;
  }
  if ( $ora_flag == 1 ) {
    if (/^\w*$/) {
      $ora_flag = 0;
      print $new_ORA;
    }
    next;
  }
  print;
}

print;

[blue]__DATA__
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 97 F 99 0
"/*/orabase" P M 90 F 95 0
"/*/orabase/data/????/dat*" P M 100 F 100 0

managed_target=SAP
"/oracle/stage*" P M 100 F 100 0

new file ..............
#FileName=fsmon.txt
#config file
#FileName=fsmon.txt
#config file
"/home" P M 90 F 95 0
"/usr" P M 95 F 98 0

managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

managed_target=SAP
"/oracle/stage*" P M 100 F 100 0
........[/blue]

Kind Regards
Duncan
 
yep - perfekt - I myself came to a similar solution, but yours is way more slim. Can you explain the regex

if (/^\w*$/) {

to me please.

Here's my code.

Code:
#!/usr/bin/perl -w
use strict;
use warnings;
###### variables#######
my $filename = "d:\/perl\/fsmon.rc";
my $newfile = "d:\/perl\/fsmon-new.rc";
my $line;
my $sub = qq~managed_target=ORA
"/orabase*" P M 90 F 95 0
"/orabase*/data/*/log*" P M 99 F 99 0
"/orabase*/data/*/data*" P M 90 F 99 0
"/orabase*/data/*/archiv" P M 75 F 90 0

~;
my @FILEREAD;
my $found=0;
##### start processing file ########
open(FILEREAD, "< $filename");
open(FILEWRITE, "> $newfile");
@FILEREAD = <FILEREAD>;
close FILEREAD;
foreach $line (@FILEREAD) {
	if ($line eq "managed_target=ORA\n") {
		$found=1;
		print FILEWRITE $sub;
		next;
	}
	if ($found==0){
		print FILEWRITE $line;
	}
	if ($found==1){
		if ($line =~ /managed_target/){
			$found=0;
			print FILEWRITE $line;
		}
	}
}
close FILEWRITE;
 
ok - the substitution works generally, but all sections below the managed_tartet=ORA are deleted. But they are still needed. Only the managed_tartet=ORA section must be replaced.

Worked OK for me when I tested the code I posted. But if you have another working solution all is well.
 
if (/^\w*$/) {

\w is the same as the character class: [a-zA-Z0-9_] sometimes called the "word" character class, it's compliment is \W, or the "non word" character class.

basically means if the line has zero or more of the characters in the class the condition is true.
 
thanks for the vote ;-)

I am glad that is working for you and i see that Kevin has kindly explained the regex

My regex is actually wrong - but it works due to the data being clean

What i meant to write was /^\s*$/

i.e. When you come across a line that is (or appears to be) blank then reset the flag back to zero

Cheers

Kind Regards
Duncan
 
Hi Duncan - Hi Kevin

thank you very much for the professional help. One of those days I hopefully will have learned reading the regex myself.

Cheers
Kind Regards

Dietmar
 
no problem dude

thank you for your kind comments & good luck with the regex's!

Kind Regards
Duncan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top