Использование sed для сохранения результата в буфере и использования его в качестве шаблона для другой команды sed

Ответ довольно прост, так как rootиспользуйте:

service tor restart

или

service tor reload
2
20.05.2021, 09:57
1 ответ

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

Я считаю полезным работать с примерами. Учитывая файл типа

green2
gold1
blue3
gold2
red4
more gold2 to find

Теперь вы хотите заменить каждое 1на 2и сохранить результирующую строку, чтобы сделать что-то, когда она появится снова. В этом примере файла вы хотели бы заменить gold2, но вы не можете этого знать, потому что в другом файле это может быть по-другому. Выход должен быть

green2
gold2
blue3
replace
red4
more replace to replace

В реальном мире могут быть похожие задачи, и вы обычно решаете их в sedследующим образом:

sed -e 's/1/2/;tfound' -e 'G;s/\(..*\)\(.*\)\n\1$/replace\2/;P;d' -e ':found' -e h inputfile

Концепция состоит в том, чтобы сохранить результирующую строку в буфере хранения и использовать обратную ссылку для сопоставления каждой строки с буфером хранения. Подробно:

  • s/1/2/это очевидная часть :вы заменяете 1на2
  • tfoundозначает переход к отметке :foundв случае замены. В этом случае строка сохраняется в ячейке хранения с h, а строка с заменой печатается (, если вы не хотите ее печатать, вы можете добавить dудаление)
  • Теперь идет часть для строк, чтобы проверить наличие нашего шаблона пространства удержания:Gдобавляет пространство удержания к текущему пространству шаблона, поэтому пространство шаблона состоит из
  • s/\(..*\)\(.*\)\n\1$/replace\2/образует две группы в текущей строке :Первая повторяется как \1после новой строки,так что это динамический шаблон в области хранения (обратите внимание, что ..*требует, чтобы шаблон был по крайней мере одним символом, поэтому мы избегаем пустого пространства хранения для соответствия ); вторая — это оставшаяся часть строки, которую нельзя удалять, поэтому мы повторно используем ее как \2в замене
  • Мы могли бы напечатать строку, если бы была сделана замена, но если замены не было, мы должны удалить добавленный материал. Мы могли бы сделать это с помощью s/\n.*//, но мы также можем использовать команду P, чтобы напечатать только первую строку, а затем dудалить, чтобы избежать вывода по умолчанию.

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

Обновление:OP пояснил, что второй этап также следует применять к исходной строке соответствия и всем последующим строкам (до нового совпадения ), поэтому

hello
world
and test it

должно стать

заменить Мир и замените его

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

sed -ne '/hello/{s//test/;h;}' -e 'G;s/\(..*\)\(.*\)\n\1$/replace\2/;P'

Опция -nподавляет все выходные данные по умолчанию, так как теперь весь желаемый вывод выполняется командой P. Для совпадающей строки(hello)выполняется подстановка (пустой шаблон означает повторное использование последнего шаблона )и помещение его в буфер хранения, затем выполняются следующие команды, поэтому следующая подстановка также выполняется в той же строке.

Обновление 2:В связанном примере строки helloвообще не должны изменяться. Вы можете сделать это с небольшой модификацией:

sed -ne '/hello/{h;s//test/;x;}' -e 'G;s/\(..*\)\(.*\)\n\1$/replace\2/;P'
2
28.07.2021, 11:30

Теги

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