5

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

OLD_STRING='<property name="webServiceHost">${jboss.bind.address}</property>'
NEW_STRING='<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'

Строки, кажется, сохранены как ожидалось:

$ echo $OLD_STRING; echo $NEW_STRING
<property name="webServiceHost">${jboss.bind.address}</property>
<!--<property name="webServiceHost">${jboss.bind.address}</property>-->

Grep'ing подтверждает, что старая строка присутствует в файле XML:

$ grep "$OLD_STRING" jboss-beans.xml
<property name="webServiceHost">${jboss.bind.address}</property>

Но следующая команда sed не выдает никаких результатов:

sed -i 's/"$OLD_STRING"/"$NEW_STRING"/g' jboss-beans.xml

Есть идеи, что мне здесь не хватает?

2 ответа2

3

Помещение переменных оболочки в одинарные кавычки отключает их интерпретацию. Вот почему ваша команда не имеет никакого эффекта.

$ echo  's/"$OLD_STRING"/"$NEW_STRING"/g'
s/"$OLD_STRING"/"$NEW_STRING"/g

Это должно быть написано так:

sed -i "s/'$OLD_STRING'/'$NEW_STRING'/g" jboss-beans.xml

Но затем переменные интерпретируются перед вызовом sed и снова содержат специальные символы:

$ echo  "s/'$OLD_STRING'/'$NEW_STRING'/g"
s/'<property name="webServiceHost">${jboss.bind.address}</property>'/'<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'/g

По этой причине у sed есть специальная функция, позволяющая определять разделители команд s/// , просто используя их, например:

sed -i "s#'$OLD_STRING'#'$NEW_STRING'#g" jboss-beans.xml

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

sed -i 's/\(<.*webServiceHost.*jboss.bind.address.*>\)/<!--\1-->/' jboss-beans.xml

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

sed -i '/webServiceHost/ s/^\(.*\)$/<!--\1-->/' jboss-beans.xml
0

Это может быть полезно для вас:
Командная строка XML манипуляции
http://xmlstar.sourceforge.net/

AFAICR
apt-get установить xmlstarlet

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .