Замена строки в нескольких файлах

Замена строки в нескольких файлах

У меня есть список файлов и соответствующих номеров строк, в которых я хочу выполнить замену:

s/LOG.error/LOG.warn

Есть и другие места, где это может произойти, и я не хочу нарушать эти строки. Как это сделать с помощью find и sed?

Файл имеет следующий формат:

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

Вот что я нашел, когда искал способ это сделать:

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

решение1

Вам нужно будет разбить файл на разделы по файлу назначения и выполнить sed -iдля каждого файла по отдельности. Предполагая, что у вас есть имена файлов и номера строк, сгруппированные по имени файла и в порядке возрастания, вы можете сделать что-то вроде

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

Это быстрый и грязный хак, который может привести к интересным и, возможно, опасным нарушениям, если имена файлов в первом столбце не являются одним токеном.

Мы по сути рефакторим ваш текстовый файл в последовательность sedскриптов. Таким образом, ваш пример будет превращен в

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

который, как вы заметите, представляет собой shскрипт, содержащий по одному sedскрипту для каждого файла.

Если вы работаете на платформе *BSD (включая Mac OS), вам нужно будет изменить значение sed -iна sed -i ''which в Awk, "sed -i \047\047"чтобы правильно вставлять одинарные кавычки, не нарушая окружающие кавычки оболочки (чтобы вся строка стала printf "sed -i \047\047 \047" }(sic)).

Связанный контент