Заменить строку в файл, предшествующий другой строке

Один раз запустите scp , а затем скопируйте его локально на удаленный сервер.

$ scp file.txt my-remote-vm-1:/tmp
$ ssh my-remote-vm-1 'for i in /tmp/conf-[0-9]-ver-[0-9]; do cp /tmp/file.txt "$i"; done'
$ ssh my-remote-vm-1 rm /tmp/file.txt
3
10.01.2019, 18:51
4 ответа

Если у вас есть несколько похожих строк в одном файле, вам нужно будет ввести:

sed -i ':a;N;$!ba; s/27020/22443/2' file

Где /2 означает, что второе совпадение будет заменено на 27020 . Вы можете протестировать команду с помощью команды sed без параметра -i, чтобы увидеть, какой результат вы получите.

В противном случае с простым sed -i 's/27020/22443/g' fileэто было бы правильно, если вы знаете, какой файл изменить.

2
27.01.2020, 21:09

Я предполагаю, что reader_0имеет host = hostanme 1, reader_1имеет host = hostname 2и так далее.

Вы можете использовать эту команду для заменыfile:

sed -i '/host = "hostname 2",/{N;s/port = 27020,/port = 22443,/}' file
3
27.01.2020, 21:09

Использование предшественника sed ed:

ed -s input <<< $'/^reader_1 =\n/^port =\nc\nport = 22443,\n.\nw\nq'

Это отправляет edстроку команд ANSI -, цитируемую здесь -, для редактирования файла. Команды в последовательности:

  1. /^reader_1 =--поиск строки, начинающейся с "reader _1="
  2. /^port =--искать оттуда строку, начинающуюся с "port="
  3. c--изменить эту строку
  4. port = 22443,--к этому тексту
  5. .--конец текста замены
  6. w--записать файл на диск
  7. q--выйтиed

Вы можете ужесточить или ослабить регулярные выражения, чтобы они соответствовали более или менее точно, в соответствии с вашими фактическими данными.

6
27.01.2020, 21:09

Это может быть лучше сделано с помощью awk, в котором вы можете использовать машинный метод состояния -:

awk '/^reader_1 = newcamd\({/ { section_found = 1} /})/ { section_found = 0 } section_found && /port = 27020,$/ { sub(/27020,$/, "22443,") } { print }' file1 > file2 && mv file2 file1

Пояснение:

Установить флаг при обнаружении начала раздела:

/^reader_1 = newcamd\({/ {
    section_found = 1
}

Очистить флаг при обнаружении конца раздела:

/})/ {
    section_found = 0
}

Подставить новый номер порта в правой части и в правой строке:

section_found && /port = 27020,$/ {
    sub(/27020,$/, "22443,")
}

Печать всех строк:

{
    print
}

Отправить вывод в файл2 (временный файл):

> file2

Если все прошло успешно, переименуйте файл2 в файл1:

&& mv file2 file1

Вы можете сделать регулярные выражения настолько свободными или жесткими, насколько вам нужно.

Этот тип кода легче читать и поддерживать, чем код sedили ed, особенно если вы отформатируете его так же, как в моем объяснении.

1
27.01.2020, 21:09

Теги

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