Я пытаюсь заменить 1-й блок текста совпадения на sed. Рассмотрим этот пример.
read -r -d '' VAR <<"EOF"
<Button3d
some text
some text
/>
<Button3d
some text
some text
/>
EOF
sed '1,/^<Button3d/,/^/>/c {
</Button\
different text\
different text\
/>\
}' <<< $VAR
Но с GNU sed я получаю следующую ошибку:
sed: -e expression #1, char 15: unknown command: `,'
Ожидаемый результат должен быть:
<Button
different text
different text
/>
<Button3d
some text
some text
/>
Некоторые предлагали использовать синтаксический анализатор XML, однако для этого простого примера это было бы полным излишеством.
Обновлено. Я не разбираю сложный XML.
@user11316197 user11316197 при использовании регулярного выражения в sed всегда используйте sed 's+regex+new-text+g' file.txt
и используйте g
только тогда, когда вы хотите заменить все вхождения, иначе просто удалите его. Разделитель +
следует использовать с регулярным выражением, а не /
.
Когда ваш sed
поддерживает -z
, вы можете использовать что-то вроде
sed -z 's#/>#\r#g; s/<Button3d[^\r]*\r//; s#\r#/>#g' <<< "${VAR}"
Обновлено: Другой текст можно вставить с помощью
sed -z 's#/>#\r#g; s/<Button3d[^\r]*\r/<Button3d\nOther text\nSecond line\n\r/; s#\r#/>#g' <<< "${VAR}"
Хм. Чем заменяете??
Поскольку '#<Button3d.*/>##
заменит как можно больше, вам нужен трюк, говорящий о замене до первого появления />
. Используемый трюк состоит в том, чтобы сначала заменить эту строку на уникальный одиночный символ (например, возврат каретки в Windows), выполнить замену и восстановить другие строки обратно на />
.
Это просто удаляет его. Он должен заменить весь блок другим текстом.
Ответ отредактирован. Использование var со строкой замены более сложно.
Где вы указываете номер матча 1-й, 2-й или 3-й???
Второй с 2
в sed -z 's#/>#\r#g; s/<Button3d[^\r]*\r/<Button3d\nOther text\nSecond line\n\r/2; s#\r#/>#g'
Это похоже на XML. Вы должны использовать синтаксический анализатор XML.