Reemplazo de una línea en varios archivos

Reemplazo de una línea en varios archivos

Tengo una lista de archivos y números de línea correspondientes donde quiero realizar la sustitución:

s/LOG.error/LOG.warn

Hay otros lugares donde esto podría ocurrir y no queremos alterar esas líneas. ¿Cómo puedo hacer esto usando find y sed?

El archivo tiene el formato:

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

Esto es lo que encontré mientras buscaba una manera de hacer esto:

cat filenames.txt | xargs sed -i '<get-line-number-here>s/LOG.error/LOG.warn' <get-file-name-here>

Respuesta1

Deberá dividir el archivo en particiones por archivo de destino y realizar operaciones sed -ien cada archivo individualmente. Suponiendo que tiene los nombres de archivo y los números de línea agrupados por nombre de archivo y en orden ascendente, puede hacer algo como

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

Este es un truco rápido y sucio que se romperá de maneras interesantes y posiblemente peligrosas si los nombres de los archivos en la primera columna no son un solo token.

Básicamente, refactorizamos su archivo de texto en una secuencia de sedscripts. Entonces tu ejemplo se convertirá en

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

Lo que notará es un shscript que contiene un sedscript para cada archivo.

Si está en una plataforma *BSD (incluido Mac OS), deberá cambiar sed -icuál sed -i ''sería en Awk "sed -i \047\047"para poder incrustar correctamente las comillas simples sin alterar las comillas del shell circundante (para que toda la línea se convierta en printf "sed -i \047\047 \047" }(sic)).

información relacionada