Заменить строку в кавычках с помощью sed

Вопрос или проблема

Я пытаюсь заменить строку внутри кавычек в файле! Вот пример:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Manager pathname="" />
<Resource auth="Container" driverClassName="org.postgresql.Driver"   maxActive="20" maxIdle="5" maxWait="10000" name="jdbc/custom" password="CHANGEIT" type="javax.sql.DataSource" url="jdbc:postgresql://10.10.10.10:5432/database" username="MyUser"/>
</Context>

Эта команда работает для нескольких ‘полей’, но не работает с именем пользователя из-за / .

# Это ОК
sed 's/\(.*password=\)[^ ]*\( .*\)/\1"NEW_VALUE"\2/' ROOT.xml

# Это НЕТ
sed 's/\(.*username=\)[^ ]*\( .*\)/\1"NEW_VALUE"\2/' ROOT.xml

Как я могу это сделать, пожалуйста?

Спасибо,

Вам нужно изменить команду

sed 's/\(.*username=\)[^ ]*\( .*\)/\1"NEW_VALUE"\2/' ROOT.xml

на

sed 's/\(.*username=\)[^ \/]*\( .*\)/\1"NEW_VALUE"\2/' ROOT.xml

потому что [^ ] означает: Каждый символ, кроме пробела. [^ \/] означает: Каждый символ, кроме пробела и/или /.

Измените на это:

sed 's/\( username="\)[^"]*/\1NEW_VALUE/' ROOT.xml

Это получит любой шаблон с пробелом + имя пользователя + двойной кавычкой до следующей двойной кавычки и заменит на первую часть и новое значение.

Чтобы исправить это, вы можете изменить разделитель в команде sed с / на другой символ, который не встречается в вашем XML-контенте, например |. Вот как вы можете изменить вашу команду sed, чтобы обрабатывать это:

sed 's|\(.*username=\)[^ ]*\(\s.*\)|\1"NEW_VALUE"\2|' ROOT.xml

Ответ или решение

Для замены строки внутри кавычек в XML-файле с помощью утилиты sed, вам нужно учитывать некоторые нюансы, связанные с синтаксисом и правилами парсинга. Давайте подробно разберем решение вашей задачи.

Проблема

В вашем исходном примере заменяется значение строки, которая содержит поле username. Однако, код, который вы привели, не работает, поскольку символ / используется в значениях, что влияет на поведение sed. Обычно, в регулярных выражениях / используется как разделитель, и его присутствие в значении вызывает сбой выполнения команды.

Решение

Существует несколько подходов, которые можно использовать для успешной замены значения username в XML-файле.

1. Изменение делиметра

Одним из решений является изменение символа-разделителя. Вместо дроби / можно использовать другой символ, который не встречается в значениях, например, |. Ваша команда sed будет выглядеть так:

sed 's|\(.*username="\)[^"]*\(".*\)|\1"NEW_VALUE"\2|' ROOT.xml

Разбор команды:

  • s|...|...| – здесь используются символы | в качестве разделителей.
  • \(.*username="\) – захватывает всю строку до username=".
  • [^"]* – захватывает все символы до следующей кавычки.
  • \(".*\) – захватывает оставшуюся часть строки, начиная с закрывающей кавычки.

Таким образом, это решение предотвращает конфликты с символом / и корректно заменяет значение.

2. Использование других подходов

Вы также можете использовать текстовые процессоры, такие как awk, или более мощные языки программирования для обработки текста, такие как Python с его библиотеками для работы с XML.

Пример с использованием Python:

import xml.etree.ElementTree as ET

tree = ET.parse('ROOT.xml')
root = tree.getroot()

for resource in root.findall('.//Resource'):
    resource.set('username', 'NEW_VALUE')

tree.write('ROOT.xml')

Это решение более устойчивое к ошибкам и обеспечит корректную структуру XML, однако он требует установки Python и некоторого времени на обучение.

Заключение

Выбор метода зависит от ваших требований к задаче и предпочтений. Изменение символа-разделителя в sed – это просто и эффективно для данной задачи. В то время как использование более мощных инструментов, таких как Python, может дать больше контроля и гибкости в случае более сложных изменений.

Постоянно обновляйте свои знания о sed и других инструментов обработки текста, чтобы выбирать подходящее решение для конкретной задачи и улучшать качество вашего кода.

Оцените материал
Добавить комментарий

Капча загружается...