Inserir texto de múltiplas linhas antes da primeira linha correspondente em um arquivo

3

queremos adicionar as seguintes linhas no arquivo log4j

log4j.appender.DRFA=org.apache.log4j.RollingFileAppender
log4j.appender.DRFA.MaxBackupIndex=100
log4j.appender.DRFA.MaxFileSize=10MB

mas essas linhas devem estar antes da primeira linha que inclui a palavra - DatePattern , e não importa se a linha está marcada ou não

#log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

ou

log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

note - no caso de a palavra DatePattern aparecer duas vezes no arquivo, as três linhas devem ser definidas somente antes da primeira linha que incluir - DatePattern

exemplo 1 (resultado esperado)

log4j.appender.DRFA=org.apache.log4j.RollingFileAppender
log4j.appender.DRFA.MaxBackupIndex=100
log4j.appender.DRFA.MaxFileSize=10MB


#log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

exemplo 2 (resultado esperado)

log4j.appender.DRFA=org.apache.log4j.RollingFileAppender
log4j.appender.DRFA.MaxBackupIndex=100
log4j.appender.DRFA.MaxFileSize=10MB


log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
    
por yael 05.08.2018 / 19:23

5 respostas

4

Se eu entendi sua pergunta corretamente, você simplesmente deseja substituir esta linha:

log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
-or-
#log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

Com estas linhas:

log4j.appender.DRFA=org.apache.log4j.RollingFileAppender
log4j.appender.DRFA.MaxBackupIndex=100
log4j.appender.DRFA.MaxFileSize=10MB
log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
-or-
#log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

Este comando GNU sed pode fazer isso:

$ sed -i 's/\(.*appender.DRFA.DatePattern=.*\)/log4j.appender.DRFA=org.apache.log4j.RollingFileAppender\nlog4j.appender.DRFA.MaxBackupIndex=100\nlog4j.appender.DRFA.MaxFileSize=10MB\n\n\n/' log4j.properties

No que diz respeito à duplicação de linhas. Você não terá esse appender definido mais de uma vez:

appender.DRFA.DatePattern

Portanto, podemos olhar mais explicitamente para essa ocorrência, em vez da linha DatePattern que você está procurando.

Exemplo de execução

Aqui está um arquivo de exemplo que tem apenas esta linha:

$ cat log4j.properties
#log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

Execute o comando sed acima neste arquivo:

$ cat log4j.properties
log4j.appender.DRFA=org.apache.log4j.RollingFileAppender
log4j.appender.DRFA.MaxBackupIndex=100
log4j.appender.DRFA.MaxFileSize=10MB
#log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
    
por 05.08.2018 / 20:02
5

Usando awk :

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

Isso imprimiria as três linhas quando a primeira coincidência de DatePattern ocorrer no arquivo. O sinalizador done é então definido como 1 , o que impede que as linhas sejam impressas novamente. O 1 à direita no final faz com que todas as linhas nos dados sejam impressas.

Se você quiser linhas vazias na saída após as três linhas, adicione \n\n ao final da última string.

A saída é gravada em newfile e, se awk não encontrar nenhum erro estranho, o original será substituído por isso assim que o processo awk terminar.

Solicitado nos comentários: Adicionando as linhas após a linha correspondente,

awk '1; 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
    }' file

Isso move o 1 (que faz a impressão de cada linha de entrada e pode ser substituído por { print } ) para antes do código que é acionado quando o padrão corresponde.

    
por 05.08.2018 / 19:39
4

Usando GNU sed , você também pode se aproximar dessa maneira:

sed -i -e '
    /DatePattern/!b

    i\
log4j.appender.DRFA=org.apache.log4j.RollingFileAppender\
log4j.appender.DRFA.MaxBackupIndex=100\
log4j.appender.DRFA.MaxFileSize=10MB

    :a;n;$!ba
' input.file

E se tiver certeza de que DatePattern não pode estar na última linha do arquivo, você também pode fazer isso:

sed -i -e '
    /DatePattern/!b
    r file2add.txt
    N;:a;n;$!ba
' input.file

onde você coloca todas as linhas a serem adicionadas em um arquivo, digamos file2add.txt . Nota: com este método, você não coloca barras invertidas no arquivo file2add.txt .

    
por 05.08.2018 / 20:29
2

Já que você marcou essa consulta com perl também, então aqui está uma maneira óbvia:

perl -pi -e '
     print <<\EOF if /DatePattern/ && !$seen++;
log4j.appender.DRFA=org.apache.log4j.RollingFileAppender
log4j.appender.DRFA.MaxBackupIndex=100
log4j.appender.DRFA.MaxFileSize=10MB
EOF
' input.file

Observação: o texto adicionado não deve conter a string autônoma EOF em uma linha sozinha. A barra invertida do heredoc é necessária, para que nenhuma variável seja expandida.

Se você não pode ter certeza das restrições acima no texto a ser adicionado, faça o seguinte:

perl -pi -e '
    next if !/DatePattern/ || $seen++;
    open my $fh, "<", "file2add.txt" or die "Could not open file for reading:$!\n";
    $_ = join "", <$fh>, $_;
' input.file
    
por 05.08.2018 / 21:03
1

Este é um trabalho bem adequado ao ed , o editor de arquivos padrão:

/DatePattern/i
log4j.appender.DRFA=org.apache.log4j.RollingFileAppender
log4j.appender.DRFA.MaxBackupIndex=100
log4j.appender.DRFA.MaxFileSize=10MB
.
wq
    
por 06.08.2018 / 11:35