Inserting after comments with AWK (or SED)

September 2009


We want to insert a block of text into a file, just before the first line that isn't a comment or an empty line, like turning this:

#
# Dit is commentaar
#

#
# Dit ook
#



line1
line2
line3
    

into this:

#
# Dit is commentaar
#

#
# Dit ook
#



This line inserted
line1
line2
line3
    

That was done with the following awk command and script:


      awk -f ./awkit lang
    

with the contents of ./awkit:

#!/usr/bin/awk

# before the first record (line), set 'inserted' to zero
BEGIN {inserted = 0}

# If inserted > 0, print the record and go to the next
inserted { print $0 ; next }

# If still processing comments/empty lines, print them an get the next record
/^#|^[\t ]*$/ { print $0 ; next }

# If not processing empties/comments any more, insert some lines, set 'inserted', and go on
{ print "This line inserted" ; inserted = 1 ; print $0 }            
    

It can be done with sed as well:


      ./sedit lang
    

with the contents of ./sedit:

#!/bin/sed -f

# With comments and empties, jump to end of script
/^#/ { b PRINT_AND_CONTINUE }
/^[ \t]*$/ { b PRINT_AND_CONTINUE }

# Does the hold space contain "inserted"?
x
s/inserted/inserted/
x
# if so, jump to conclusion
t PRINT_AND_CONTINUE

# Now we're at the first non-empty non-comment line
# and we put "inserted" in hold space to remember that we 've already done the insert
# first, put the pattern in hold space
h
# substitute the contents of the (now empty) pattern space with "inserted"
s/^.*$/inserted/
# exchange the pattern and hold spaces
x
# We've got "inserted" in the hold space, and the old pattern back in pattern space
# Insert some lines
i This line inserted\
and this line too
# Fall through to the end to print the very line that triggered this action

: PRINT_AND_CONTINUE
# Although no commands here, something actually happens:
# the pattern space is printed to output