как использовать sed для замены N-й строки на M-ю строку в том же файле на номера строк - PullRequest
2 голосов
/ 27 сентября 2019

Вот моя проблема:

  • Дан текстовый файл.
  • Данные в каждой строке неизвестны.
  • Необходимо заменить строку 3 на строку 5.
  • Номер строки, подлежащей замене, и номер строки, подлежащей замене, даны и являются постоянными.
  • Номера строк никогда не являются ни первой, ни последней строкой.
  • Количество строк в файле не изменяется

Перед запуском кода

A34JC
P1@%NWA]
MM1              //Line to be replaced
M@K(FD
BWKD             //Line to replace with
Z

После запуска кода

A34JC
P1@%NWA]
BWKD             //Data in Line 3 was replaced with the data from line 5
M@K(FD
BWKD
Z

Я действительно не против использования shell, sed (или awk, хотя я не знаком с этим).Из того, что я здесь увидел, я попробовал следующее

sed 3s/.*/???/ file1.txt > file2.txt

Мне стыдно сказать, что я пробовал на ???.Я знаю, что могу вставить туда текст вручную, но проблема в том, что я не знаю, что держит строка данных 5.

Я также пробовал различные способы замены, но это было еще хуже.

sed 3d;5r file1.txt file1.txt > file2

короче, я не в курсе.

Обновления

Первое решение Потонга не сработало для меня, но альтернативная работа.Теперь у меня есть вопрос продолжения.

Итак, ситуация такова - мне приходится все время повторять очень раздражающий процесс.Не вдаваясь в подробности:

  • Я использую Windows.
  • У меня есть текстовый файл, содержащий номера идентификаторов процессов, и под каждым из номеров находятся настройки, которые принадлежатконкретный процесс.
  • Идентификатор процесса изменяется каждый раз, когда я перезапускаю процесс.
  • Новый идентификатор процесса автоматически записывается в текстовый файл.
  • Вместо установки параметра процесса изпо порядку, я просто копирую новый случайный сгенерированный идентификационный номер процесса и стираю данные настроек, которые сейчас просто нежелательны.
  • В данный момент одновременно запущено 4 таких процесса.Поэтому они всегда добавляются и изменяются вместе.

Вот то, что я до сих пор вычислял:

Примечание: я добавил -i, чтобы сохранить изменения, сделанные в одном и том же файле

.\sed -E -i '28{:a;N;60!ba;s/[^\n]*(.*\n(.*))/\2\1/}' config.txt
.\sed -E -i '36{:a;N;64!ba;s/[^\n]*(.*\n(.*))/\2\1/}' config.txt
.\sed -E -i '44{:a;N;68!ba;s/[^\n]*(.*\n(.*))/\2\1/}' config.txt
.\sed -E -i '52{:a;N;72!ba;s/[^\n]*(.*\n(.*))/\2\1/}' config.txt

Вы можете видеть 28,36,44,52 и 60,64,68,72 серии.

Вот что мне нужно для получения дополнительной помощи:

Я хочу выполнить все 4 команды автоматически, например, в виде файла .bat или чего-то подобного.Может ли он работать с использованием файла .bat?

Я знаю, что cmd требует, чтобы я удалил 'из команды, и может добавить строку вместо перезаписи.Это хорошо работает в Power Shell, но покажите, как сделать .bat файл для запуска в Power Shell?

Я хочу добавить команду в конце, чтобы удалить все из строки 60 и далее.Как мне это сделать?

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Это может работать для вас (GNU sed):

sed -e '3{e sed -n "5p" file' -e 'd}' file

Оценивает sed внутри sed с помощью команды e.

Альтернатива:

sed -E '3{:a;N;5!ba;s/[^\n]*(.*\n(.*))/\2\1/}' file
0 голосов
/ 27 сентября 2019

Для данного примера вы можете использовать это:

sed '3d;4{h;d};5{p;x;p;x}' file1.txt >file2.txt
  • 3d: удалить строку 3
  • 4{h;d}: скопировать строку 4 для хранения пробела;удалить строку 4 (пока)
  • 5{p;x;p;x}: вывести строку 5 (становится строкой вывода 3);обменный трюм и шаблон пространства;напечатать ранее проведенную строку 4;повторно замените удержание и пространство шаблона для автоматической печати строки 5

Если между строкой, подлежащей замене и заменой, имеется более одной строки, например, 3 и 7, соответственно, мы бынужна дополнительная команда для добавления строк между:

sed '3d;4{h;d};5,6{H;d};7{p;x;p;x}' file1.txt >file2.txt
...