Как найти и заменить несколько строк текста в файле, который содержит пробел и представлен переменной? - PullRequest
0 голосов
/ 24 октября 2018

У меня есть файл input.txt, содержащий следующий текст:

abc def
ghi jkl
mno pqr
stu vwx

Я могу заменить две строки в файле этой командой:

perl -i -p0e 's/ghi jkl\nmno pqr/zyx wvu\ntsr qpo/s' input.txt

Однако янужно, чтобы строки поиска и замены были в переменных:

search_s="ghi jkl\nmno pqr"
replace_s="zyx wvu\ntsr qpo"

Но теперь эта команда не работает с переменными:

perl -i -p0e 's/'$search_s'/'$replace_s'/s' input.txt

Я получаю сообщение об ошибке "Шаблон подстановки незаканчивается в -е строке 1. ".Кажется, проблема в пробелах в переменной $ search_s.Я пробовал различные методы кодирования пространства, чтобы эта работа работала без успеха.

Примечание: я использую команду perl, потому что она хорошо обрабатывает поиск и замену, содержащую \n в файле.Я пробовал sed, но не очень хорошо.

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

Спасибо, Роб

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Если вы хотите выполнить сопоставление более чем на одну строку, awk интересно.

С помощью awk вы можете справиться с этим по-разному.
Мое решение - хранить каждую строку в массиве иизмените сохраненные данные, когда я увижу, что у меня есть две совпадающие строки.

awk -v line1="ghi jkl" -v line2="mno pqr" '
   {a[NR]=$0}
   $0==line1 {m1=1; next}
   $0==line2 {a[NR-1]="zyx wvu"; a[NR]="tsr qpo"; m1=0}
   END {for (i=1;i<=NR;i++) print a[i]}
   ' input.txt

Другое решение, без массива, запоминает первую строку и печатает ее, когда вторая строка не завершает совпадение.При совпадении выведите строки замены и не забудьте инструкцию END для печати последней строки (если она не является частью совпадения).

0 голосов
/ 24 октября 2018

Путаница здесь заключается в цитировании оболочки.Когда вы пишете

perl -i -p0e 's/'$search_s'/'$replace_s'/s' input.txt

Оболочка анализирует это и вызывает perl со следующими аргументами: -i -p03 s/ghi jkl\nmno pqr/zyx wvu ... Это не то, что выхочу.Это происходит потому, что оболочка выполняет разбиение слов после расширения ваших переменных.Чтобы предотвратить это, вам нужно процитировать аргументы:

perl -i -p0e "s/$search_s/$replace_s/s" input.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...