Вопрос или проблема
Я пытаюсь заменить строку внутри кавычек в файле! Вот пример:
<?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
и других инструментов обработки текста, чтобы выбирать подходящее решение для конкретной задачи и улучшать качество вашего кода.