wcj75019 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
I am removing the line with bgs in it. If it exists. Then,I am trying to add this line after the 'cron':
watch process procAlive 'bgs' 18 0x2 60 'Production Critical: bgs fail +ure. Restarting bgs' '/opt/EMPsysedge/bin/sysedge.sh'
Here is part of the file I'm trying to modify:
watch process procAlive 'cron' 1 0x2 60 'Production Critical: cro +n failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'inetd' 2 0x2 60 'Production Critical: in +etd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'sendmail' 3 0x2 60 'Production Critical: sen +dmail failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'syslogd' 4 0x2 60 'Production Critical: sy +slogd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'automountd' 5 0x2 60 'Production Critical: au +tomountd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'xntpd' 6 0x2 60 'Production Critical: xn +tpd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'itaagtd' 7 0x2 60 'Production Critical: it +aagtd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh'
here are my errors: They have to do with my regex.
Use of uninitialized value at ./b.o-n line 16, <IN> chunk 86. Use of uninitialized value at ./b.o-n line 17, <IN> chunk 86. Use of uninitialized value at ./b.o-n line 16, <IN> chunk 87. Use of uninitialized value at ./b.o-n line 17, <IN> chunk 87. Use of uninitialized value at ./b.o-n line 16, <IN> chunk 88. Use of uninitialized value at ./b.o-n line 17, <IN> chunk 88. Use of uninitialized value at ./b.o-n line 16, <IN> chunk 89.
Here is my script.
Suggestions?
Thanks!
#!/usr/bin/perl -w use strict; my $cf_dir = "/fmac/sysadm/admin/sysedge/sys/sysedge/cf/"; my $CF = "watch process procAlive 'bgs' 18 0x2 60 'Production Critical +: bgs failure. Restarting bgs' '/opt/EMPsysedge/bin/sysedge.sh'"; open CF_FILES, "Servers.cf" or die "Can't Open Servers.cf file: $!"; #open CF_FILES, "Servers.test" or die "Can't Open Servers.test file: +$!"; my @cf_f=<CF_FILES>; #close CF_FILES; foreach my $cf(@cf_f) { chomp $cf; open IN, "$cf_dir/$cf" or die "Can't open '$cf' for input: $!\n"; #open OUT, ">$cf_dir/$cf.tmp" or warn "Can't write '$cf_dir/$cf.tmp': +$!\n"; open OUT, ">/tmp/$cf.tmp" or warn "Can't write '/tmp/$cf.tmp': $!\n"; my $file = do { local $/; <IN>}; s/^watch.*?'bgs'.*?sh'$//; s/^(watch.*?'cron'.*?sh'$)/$1\n$CF\n/; print OUT $file; } close OUT or die "Can't close filehandle OUT properly: $!\n"; chdir "/$cf_dir"; #rename "$cf.tmp", "$cf"; #}

Replies are listed 'Best First'.
Re: regex problem?
by CountZero (Bishop) on Mar 22, 2008 at 08:59 UTC
    Don't overdo the <code> tags thing! Just include the code in it and not the text of the node.

    Now on to the problem.

    I'm quite sure the program doesn't do what you think it is doing.

    To make matters clearer I have pared down the program to its bare minimum:

    #!/usr/bin/perl -w use strict; my $CF = "watch process procAlive 'bgs' 18 0x2 60 'Production Critical +: bgs failure. Restarting bgs' '/opt/EMPsysedge/bin/sysedge.sh'"; my $file = do { local $/; <DATA>}; s/^watch.*?'bgs'.*?sh'$//; s/^(watch.*?'cron'.*?sh'$)/$1\n$CF\n/; print $file; __DATA__ watch process procAlive 'cron' 1 0x2 60 'Production Critical: cro +n failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'inetd' 2 0x2 60 'Production Critical: in +etd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'sendmail' 3 0x2 60 'Production Critical: sen +dmail failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'syslogd' 4 0x2 60 'Production Critical: sy +slogd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'automountd' 5 0x2 60 'Production Critical: au +tomountd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'xntpd' 6 0x2 60 'Production Critical: xn +tpd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'itaagtd' 7 0x2 60 'Production Critical: it +aagtd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh'
    Now you see that you read as one string the whole of each file into $file and then you operate your regexen on the default variable $_ which however you did not load with anything beforehand, hence the Use of uninitialized value warnings and finally you print the unchanged $file back to disk.

    Don't try to be too clever and do it all at once! You need to do two things:

    1. remove the line with bgs in it; and
    2. add the $CF line after the line with cron in it.
    As these are two separate things let's do them separately and as the unit on which you work is the line, let's do it line-by-line.
    #!/usr/bin/perl -w use strict; my $CF = "watch process procAlive 'bgs' 18 0x2 60 'Production Critical +: bgs failure. Restarting bgs' '/opt/EMPsysedge/bin/sysedge.sh'"; while (<DATA>) { next if /bgs/; # skip printing the line with 'bgs' print; # print the line just read in print "$CF\n" if /cron/; # add '$CF' if we just printed the lin +e with 'cron' } __DATA__ watch process procAlive 'cron' 1 0x2 60 'Production Critical: cro +n failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'inetd' 2 0x2 60 'Production Critical: in +etd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'sendmail' 3 0x2 60 'Production Critical: sen +dmail failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'syslogd' 4 0x2 60 'Production Critical: sy +slogd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'automountd' 5 0x2 60 'Production Critical: au +tomountd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'xntpd' 6 0x2 60 'Production Critical: xn +tpd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh' watch process procAlive 'itaagtd' 7 0x2 60 'Production Critical: it +aagtd failure. Call USA POC' '/opt/EMPsysedge/bin/sysedge.sh'

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Voila...Brilliant. Thanks Count