Похоже, вы пытаетесь сопоставить двухсимвольную последовательность \n
, в отличие от одиночного символа новой строки, который вместе они представляют в некоторых контекстах. Между ними есть огромная разница.
В качестве примера вы представили
sed 's/$string/$line/g' file.txt
, но это не сработает совсем, потому что ссылки на переменные не раскрываются в одиночных кавычках. Это не имеет ничего общего со значениями переменных оболочки string
и line
.
Но давайте рассмотрим эти значения:
$string="The cat is green.\n"
$line="Sunny day today.\n"
[лишние пробелы удалены.]
Конечно, проблема, на которой вы сосредотачиваетесь, заключается в том, что sed
распознает \n
как код для символа новой строки, но у вас также есть проблема в том, что в регулярном выражении символ .
соответствует любой символ, поэтому, если вы хотите, чтобы он воспринимался как литерал, его тоже нужно экранировать (в шаблоне, но не в замене). Если вы пытаетесь поддерживать поиск и замену произвольного текста, то вам также нужно экранировать другие символы.
Отвечая на поставленный вопрос (исключая только \n
последовательностей), вы можете сделать это:
sed "s/${string//\\n/\\\\n}/${line//\\n/\\\\n}/g"
Форма расширения параметра ${foo//pat/repl}
выполняет подстановку шаблона для расширенного значения, но следует помнить, что шаблон (pat
) интерпретируется в соответствии с правилами глобализации оболочки, а не как регулярное выражение. Эта конкретная форма заменяет каждый вид узора; Прочтите руководство по bash, чтобы узнать, какие альтернативы соответствуют только первому появлению и / или соответствуют только началу или концу значения параметра. Также обратите внимание на дополнительное удвоение символов \
в подстановке шаблона - их также нужно экранировать для оболочки.
Учитывая ваши определения переменных, эта команда будет эквивалентна этой:
sed 's/The cat is green.\\n/Sunny day today.\\n/g'
Другими словами, именно то, что вы хотели. Однако, опять же, имейте в виду: это не общее решение для произвольного поиска и замены. Если вы хотите , что , то вам нужно изучить руководство sed
, чтобы определить, какие символы должны быть экранированы в регулярном выражении, а какие - в замене. Более того, я не вижу способа сделать это с помощью только одной замены шаблона для каждой переменной.