The following awk syntax will add the 3 lines in the file before the line with the word - 'DatePattern':

$ awk 'done != 1 && /DatePattern/ {
    print "log4j.appender.DRFA=org.apache.log4j.RollingFileAppender"
    print "log4j.appender.DRFA.MaxBackupIndex=100"
    print "log4j.appender.DRFA.MaxFileSize=10MB"
    done = 1
    } 1' file >newfile && mv newfile file

the problem is that awk does not care if the lines already exist, so what needs to be added to the awk, in order to insert the lines only if lines are not already present?

Other example

In this case we want to add before the line with word 'HOTEL' the names 'trump', 'bush', & 'putin', but only in the case where the names do not exists:

$ awk 'done != 1 && /HOTEL/ {
    print "trump"
    print "bush"
    print "putin"
    done = 1
    } 1' file >newfile && mv newfile file

2 Answers 2


You could do this as follows:

# store the 3 lines to match in shell variables

# function that escapes it's first argument to make it palatable
# for use in `sed` editor's `s///` command's left-hand side argument
esc() {
    printf '%s\n' "$1" | sed -e 's:[][\/.^$*]:\\&:g'

# escape the lines
line_1_esc=$(esc "$line_1")
line_2_esc=$(esc "$line_2")
line_3_esc=$(esc "$line_3")

# invoke `sed` and fill up the pattern space with 4 lines (rather than the default 1)
# then apply the regex to detect the presence of the lines 1/2/3.
sed -e '
' input.file

Based on the assumption that the order of the names doesn't matter, and they would occur always in a pack of three, try

awk '
BEGIN           {INSTXT = "trump" ORS "bush" ORS "putin"
                 for (n = split (INSTXT, T, ORS); n; n--) PRES[T[n]]

!(LAST in PRES) &&
/HOTEL/         {print INSTXT

                {LAST = $0
' file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.