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

Hello Monks, I can't get my script to add another if statement after $1. This is the file I want to modify: #!/sbin/sh # Run rctladm to configure system resource controls based on the setti +ngs # previously saved by rctladm. See rctladm(1m) for instructions on ho +w to # modify resource control settings. # if [ -f /etc/rctladm.conf ] && [ -x /usr/sbin/rctladm ]; then /usr/sbin/rctladm -u fi I want to add another if statement after the last if/fi. Thanks,
#!/usr/bin/perl -w use strict; open SYS, "sysetup"; open OUT, '>', "/tmp/sysout"; my $here=<<HERE; if /usr/bin/pgrep -x -u 0 -P 1 ltps& >/dev/null 2>&1; +then echo "$0: ltps is already running" exit 0 fi HERE while(<SYS>){ s/^(if.*rctladm.conf.*?fi)/$1\n$here/m; print OUT; }

Replies are listed 'Best First'.
Re: add after $1
by hipowls (Curate) on Mar 20, 2008 at 22:25 UTC

    You are reading in single lines and then testing if that line has an 'if' and a 'fi' in it. Since the if statement you are looking for spans multiple lines you won't find it that way.

    Your choices are to read in the entire script to a single string or to process the file a line at a time remembering the state of your search. The first is easiest and, assuming your script is not several hundred Megabytes in size, practical.

    use strict; use warnings; my $here=<<HERE; if /usr/bin/pgrep -x -u 0 -P 1 ltps& >/dev/null 2>&1; +then echo "$0: ltps is already running" exit 0 fi HERE my $file = do { local $/; <DATA> }; $file =~ s/^(if.*?rctladm\.conf.*?fi$)/$1\n$here/ms; print $file; __DATA__ # Run rctladm to configure system resource controls based on the setti +ngs # previously saved by rctladm. See rctladm(1m) for instructions on ho +w to # modify resource control settings. # if [ -f /etc/rctladm.conf ] && [ -x /usr/sbin/rctladm ]; then /usr/sbin/rctladm -u fi
    produces
    # Run rctladm to configure system resource controls based on the setti +ngs # previously saved by rctladm. See rctladm(1m) for instructions on ho +w to # modify resource control settings. # if [ -f /etc/rctladm.conf ] && [ -x /usr/sbin/rctladm ]; then /usr/sbin/rctladm -u fi if /usr/bin/pgrep -x -u 0 -P 1 ltps& >/dev/null 2>&1; +then echo "Perl-1.pl: ltps is already running" exit 0 fi
    You may want to look at the indenting of your replacement text.

      SWEEEET! Thank You hipowls!
Re: add after $1
by NetWallah (Canon) on Mar 20, 2008 at 22:11 UTC
    Update::I forgot to mention - you need to slurp the file, as hipowls(++) indicates below.

    Your regex needs two changes:

    • Escape the period
    • Add the \s modifier.
             From "perldoc perlre":
                 Used together, as /ms, they let the "." match any character whatsoever, while still allowing "^" and "$" to match, respectively, just after and just before newlines within the string.
    This works:
    s/^(if.*rctladm\.conf.*fi)/$1\n$here/sm;
    However, may I suggest the following alternatives:
    • Replace the entire shell script with perl.
    • Insert a line at the end of the original script, that calls another (bash) script. Use perl to generate the second script. This way, the first script remains unmodified - easier to enhance and debug.

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

      For some reason. Still, the $here doesn't print after the last fi. Thanks,