how to append a block of statements after another block in the file

Hi
I need to append the following block of statements in the middle of the file:
#
openpipe tsdbdwn2
set -x
exec >> /tmp/tsdbdwn2.fifo 2>&1
#
This needs to be appended right after another block of statements:
if test $# -eq 0 ;then
echo "Safety check - do you really wish to run" $0 " on " `hostname` "?"
read safety
case $safety in
y|yes|Y|YES|Yes ) ;;
* ) echo $0: aborting ; exit 1 ;;
esac
fi

Is there an awk/sed commands which will allow me to do that, since I heed to update multiple files. Thanks a lot for any help.

The smart answer is "no there is no easy way to do this. Edit the files yourself".

However, I took it as a challenge and came up with a solution, such as it is.
It will insert the new code multiple times, if necessary.

It's possible to get the wrong result if there is a lot of duplicate code in the file
and the lines follow each other with no breaks of any kind.
This is unlikely.

First, you need a file with the lines you want to insert .
newcode file:
#

openpipe tsdbdwn2
set -x
exec >> /tmp/tsdbdwn2.fifo 2>&1
#

You need a file containing the block of code which needs to be followed by the new code .
codepattern file:

if test $# -eq 0 ;then
echo "Safety check - do you really wish to run" $0 " on " `hostname` "?"
read safety
case $safety in
y|yes|Y|YES|Yes ) ;;
* ) echo $0: aborting ; exit 1 ;;
esac
fi

And you need this script which finds sequences of matches against the code patterns
and generates sed commands to insert the new code wherever it is needed.

#!/bin/sh


case "$1" in "" )
        echo usage : $0 newcode_file existingblock_file  inputfile... 1>&2
        exit 0
        ;;
esac


newcodefile=$1
patternfile=$2
shift
shift
patternlines=`cat $patternfile | wc -l`
patternlines=`echo $patternlines`


for infile in "$@"
do

  # get list of matches for patterns, with line numbers
  fgrep -n -f $patternfile $infile  | \
  nawk -F: -v seqlen=$patternlines '
     #{ print "last=" last " seq=" seq " f1=" $1 "  " $2 ;}

    last == "" { last = $1 ; next }     # initialize

    {
        # check for match with sequential line number
        if ($1 == (last + 1) ) {
                # sequential match; check length of sequence
                if  (++seq == seqlen) {
                        # "add after " $1 " : " $0;
                        print $1        # print line number of
                                        # end of code block matched
                }
        } else {
                # not sequential any more - start over
                seq = 1         # first match in sequence
        }
    }

    { last = $1}
    ' - | (
                echo sed -e \'\' '\c'
                while read line
                do
                # output sed command to read new code into file
                        echo "-e '${line}r $newcodefile' \c"
                done
                echo "$infile > $infile.new"
        )
done

The output is a set of sed commands, which you can put in a file as a script,
or just pipe to "sh -x " to see them run.

$ ./insertcode
usage : ./insertcode newcode_file existingblock_file inputfile...
  

$ ./insertcode newcode codepattern f1 f2 f3
sed -e '' -e '20r newcode' f1 > f1.new
sed -e '' -e '19r newcode' f2 > f2.new
sed -e '' -e '20r newcode' -e '30r newcode' -e '49r newcode' f3 > f3.new
$ sed -e '' -e '20r newcode' f1 > f1.new
$ diff f1 f1.new
20a21,25
> #
> openpipe tsdbdwn2
> set -x
> exec >> /tmp/tsdbdwn2.fifo 2>&1
> #

awesome solution, nobody8.

i'll present my solution, too, but just cause it's an interesting paradigm
that can be modified to do almost anything.


for file in `cat my_list_of_files_to_edit` ; do

vi +/"Safety check - do you really wish to run" $file << EOF
:/^fi
O#
openpipe tsdbdwn2
set -x
exec >> /tmp/tsdbdwn2.fifo 2>&1
#
^[:wq
EOF

done

where ^[ is actually the ESCAPE character.

Thanks a lot guys!!!! This is what i need :slight_smile:

Indeed - I like this a lot.
This is an excellent approach if the files to be edited have a unique and easily found
insertion point and it is safe to stuff in the change.

Simpler is better.

thanks, nobody.