awk + anexar linhas antes da palavra capturada apenas se as linhas não estiverem definidas no arquivo

0

A seguinte sintaxe awk adicionará as 3 linhas no arquivo antes da linha com a palavra - '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

o problema é que awk não se importa se as linhas já existem, então o que precisa ser adicionado ao awk , para inserir as linhas somente se as linhas ainda não estiverem presentes?

Outro exemplo

Neste caso, queremos adicionar antes da linha com a palavra 'HOTEL' os nomes 'trump', 'bush', & 'putin', mas apenas no caso em que os nomes não existem:

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

2 respostas

1

Você pode fazer isso da seguinte maneira:

# store the 3 lines to match in shell variables
line_1="log4j.appender.DRFA=org.apache.log4j.RollingFileAppender"
line_2="log4j.appender.DRFA.MaxBackupIndex=100"
line_3="log4j.appender.DRFA.MaxFileSize=10MB"

# 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 '
    1N;2N;$!N
    '"/^$line_1_esc\n$line_2_esc\n$line_3_esc\n.*DatePattern/"'!D
    :a;n;$!ba
' input.file
    
por 07.08.2018 / 06:06
0

Com base no pressuposto de que a ordem dos nomes não importa, e eles ocorreriam sempre em um pacote de três, tente

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
                }
1
' file
    
por 07.08.2018 / 12:32