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

319
ayushgp

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

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> 
0

1 ответ на вопрос

1
tripleee

Вам нужно будет разбить файл на разделы по конечному файлу и выполнить 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 ''на Awk "sed -i \047\047", чтобы правильно вставлять одинарные кавычки, не нарушая цитирование окружающих оболочек (так что вся строка становится printf "sed -i \047\047 \047" }(sic)).

Что я могу сделать, если я также хочу сначала найти файл в каталоге, а затем выполнить его по этому пути каталога. У меня нет полного пути. ayushgp 6 лет назад 0
Я не понимаю ваш дополнительный вопрос. У вас есть файл с именами файлов и номерами строк, но вы не знаете, к каким точным файлам в дереве каталогов это относится? Или у вас есть дерево каталогов, где какой-то каталог может содержать этот файл, и вы хотите выполнить его относительно этого каталога? tripleee 6 лет назад 0
У меня есть список файлов. Foobar.java например. Он находится где-то в pwd и является единственным файлом с таким именем. В списке, который у меня есть, у меня просто есть имя, а не полный путь к Foobar.java. Поэтому я хочу сначала применить поиск к этому имени, а затем передать его в awk, как вы предложили. ayushgp 6 лет назад 0
найти. -name Foobar.java -execdir что-нибудь` найдет файл и выполнит `что-то` в этом каталоге. Возможно, вам придется исправить это так, чтобы «что-то» не заботилось о том, в каком каталоге вы находились, когда вы его запустили (используйте абсолютный путь к входному файлу или, возможно, решите рефакторинг, если вам нужно сделать это более одного раза или дважды). tripleee 6 лет назад 0
Если вам это нужно более одного или двух раз, возможно, сначала подумайте, как вы создаете этот входной файл. tripleee 6 лет назад 0
Я буду использовать это, чтобы воспроизвести этот файл, а затем использовать sed, чтобы заменить, как вы предложили ayushgp 6 лет назад 0

Похожие вопросы