Sed в скрипте Bash-замена причины ошибки содержимого переменной


У меня есть сценарий Bash:

var="
<Location /webdav/vendor1>
 DAV On
 AuthType Digest
 AuthName "rw"
 AuthUserFile /etc/password/digest-password
 Require user test123456
</Location>

<Location /webdav/limited/vendor1/demo>
 Dav On
 AuthType Digest
 AuthName "ro"
 AuthUserFile /etc/password/digest-password-test2
<LimitExcept GET HEAD OPTIONS PROPFIND>
deny from all 
</LimitExcept>
</Location>
"

sed -i -e "s/somestringX/${var}/g" change.txt

Который возвращает ошибку: sed: - e выражение #1, char 9: unterminated' s ' команда

Когда $var - это однострочная / многострочная строка без специальных знаков типа /"', все работает нормально.

Я предполагаю, что проблема заключается в содержании моего $var, но я не знаю, что делать, чтобы заставить его работать.

Каким может быть решение этой проблемы?

3 3

3 ответа:

Sed также может использовать любой символ в качестве разделителя для команды "s". В основном, sed принимает все, что следует за "s" в качестве разделителя. Таким образом, вы можете изменить свою команду на что-то вроде:

sed -i -e "s_somestringX_${var}_g" change.txt

Необходимо убедиться, что разделитель не является частью целевой переменной.

Вы должны заменить все косые черты на экранированные косые черты, будучи \/. Это подойдет для большинства текстов. Если ваш текст, однако, будет содержать &, Избегайте и этого. Любые обратные косые черты также должны быть экранированы, как \\

Поскольку ваш текст, похоже, не содержит амперсандов или обратных косых черт, это должно сделать:

sed -i -e "s/somestringX/${var//\//\\\/}/g" change.txt

Это кажется довольно сложным, но мы просто заменим / на \/. Bash может сделать это с ${string//substring/replacement}, но мы должны избежать косых черт и обратных косых черт.

Вы можете попробовать awk

awk -v v="$var" '{gsub("somestringX",v); print}' change.txt > newfile.txt
Единственное отличие здесь заключается в том, что он не будет изменять файл change.txt на месте, как это делает sed с опцией -i. Это перенаправит результат на newfile.txt

Или если вы хотите сделать то же самое, что и sed -i

awk -v v="$var" '{gsub("somestringX",v); print}' change.txt > newfile.txt && mv newfile.txt change.txt