Substituindo uma linha em vários arquivos

0

Eu tenho uma lista de arquivos e números de linha correspondentes onde eu quero realizar a substituição:

s/LOG.error/LOG.warn

Existem outros locais onde isso pode ocorrer e não querem incomodar essas linhas. Como posso fazer isso usando o find e o sed?

O arquivo é formatado como:

FooBar.java 125
FooBar.java 180
FooBar2.java 128

Isso é o que eu encontrei enquanto procurava uma maneira de fazer isso:

cat filenames.txt | xargs sed -i '<get-line-number-here>s/LOG.error/LOG.warn' <get-file-name-here>
    
por ayushgp 11.04.2018 / 12:58

1 resposta

1

Você precisará dividir o arquivo em partições por arquivo de destino e executar sed -i em cada arquivo individualmente. Supondo que você tenha os nomes de arquivos e números de linha agrupados por nome de arquivo e em ordem crescente, você pode fazer algo como

awk '$1 != prev { if (prev) print "7 " prev;
    prev=$1;
    printf "sed -i 7" }
  { print $2 "s/LOG\.error/LOG.warn/" }
  END { if (prev) print "7 " prev }' filenames.txt | sh

Este é um hack rápido e sujo que irá quebrar de maneira interessante e possivelmente perigosa se os nomes dos arquivos na primeira coluna não forem um único token.

Basicamente, refatizamos seu arquivo de texto em uma sequência de sed scripts. Então, seu exemplo será transformado em

sed -i '125s/LOG\.error/LOG.warn
180s/LOG\.error/LOG.warn/
' FooBar.java
sed -i '128s/LOG\.error/LOG.warn/
' FooBar2.java

que você notará é um script sh que contém um script sed para cada arquivo.

Se você estiver em uma plataforma * BSD (incluindo o Mac OS), precisará alterar sed -i para sed -i '' , o que no Awk seria "sed -i 77" para incorporar aspas simples sem prejudicar as citações do shell ao redor ( para que toda a linha se torne printf "sed -i 77 7" } (sic)).

    
por 11.04.2018 / 13:13

Tags