Редактирование XML-файла из оболочки bash

#linux #bash #shell

#linux #bash #оболочка

Вопрос:

Хотите отредактировать XML-файл с помощью сценария оболочки bash. Я застрял в поиске решения — пожалуйста, поделитесь своим предложением, если это можно решить с помощью сценария оболочки bash.

Входной файл (будет сохранен на сервере):

 <?xml version="1.0" encoding="UTF-8"?>
<properties>
	<directories installDir="/fs0/">
		<directoriesInstance id="sharedDir" path=""/>
		<directoriesInstance id="loaderInput" path="/fs0/share/iad/input"/>
		<directoriesInstance id="loaderProcessing" path="/fs0/share/iad/processing"/>
		<directoriesInstance id="loaderError" path="/fs0/share/iad/error"/>
		<directoriesInstance id="loaderCompleted" path="/fs0/share/iad/completed"/>
	</directories>
  
  <applicationServerInstance id="app" serviceName="App Server" rmiPort="15001" jvmParameters="-Xmx3072m -Xms512m -XX:-UseGCOverheadLimit -XX:MaxPermSize=196m -Dsun.lang.ClassLoader.allowArraySyntax=true -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/fs0/clarity1/clarity/logs -Xloggc:/fs0/clarity1/clarity/logs/app_gc.log -XX: PrintGCDetails -XX: PrintGCTimeStamps -XX: PrintHeapAtGC -Dcustom.properties=/fs0/share/custom.properties" maxThreads="1000" programParameters="" distributed="false" runJobScheduler="false" useSSO="true" maxConcurrentJobs="10" runProcessEngine="false" messageTimeToLive="120" messageReceiverInterval="5" exceptionRunInterval="normal" maxXmlNodesLimit="150000"/>
  <applicationServer>
		<applicationServerInstance id="app" serviceName=" App Server" rmiPort="15001" jvmParameters="-Xmx3072m -Xms512m -XX:-UseGCOverheadLimit -XX:MaxPermSize=196m -Dsun.lang.ClassLoader.allowArraySyntax=true -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/fs0/clarity1/clarity/logs -Xloggc:/fs0/clarity1/clarity/logs/app_gc.log -XX: PrintGCDetails -XX: PrintGCTimeStamps -XX: PrintHeapAtGC -Dcustom.properties=/fs0/clarity1/share/custom.properties" maxThreads="1000" programParameters="" distributed="false" runJobScheduler="false" useSSO="true" maxConcurrentJobs="10" runProcessEngine="false" messageTimeToLive="120" messageReceiverInterval="5" exceptionRunInterval="normal" maxXmlNodesLimit="150000"/>
	</applicationServer>

</properties>  

В приведенном выше фрагменте я хотел выполнить поиск по тегу applicationServerInstance и посмотреть, есть ли у него Dcustom.properties=/fs0/clarity1/share/custom.properties в теге jvmproperties — если он не существует, я хотел добавить в файл и сохранить файл.
Все должно быть в сценарии оболочки bash.

Я хочу добавить значение -Dcustom.properties=/fs0/share/custom.properties к атрибуту jvmParameters в теге applicationServerInstance, если он не существует. В приведенном выше примере он имеет это значение, но в случае, если оно не существует, я хотел добавить это -значение Dcustom.properties=/fs0/share/custom.properties.

Скажем, например, я должен добавить значение-Dcustom.properties=/fs0/share/custom.properties к атрибуту jvmParameters в теге applicationServerInstance в приведенный ниже фрагмент.

 <applicationServerInstance id="app" serviceName=" App Server" rmiPort="15001" jvmParameters="-Xmx3072m -Xms512m -XX:-UseGCOverheadLimit -XX:MaxPermSize=196m -Dsun.lang.ClassLoader.allowArraySyntax=true -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/fs0/clarity1/clarity/logs -Xloggc:/fs0/clarity1/clarity/logs/app_gc.log -XX: PrintGCDetails -XX: PrintGCTimeStamps -XX: PrintHeapAtGC " maxThreads="1000" programParameters="" distributed="false" runJobScheduler="false" useSSO="true" maxConcurrentJobs="10" runProcessEngine="false" messageTimeToLive="120" messageReceiverInterval="5" exceptionRunInterval="normal" maxXmlNodesLimit="150000"/>  

Комментарии:

1. jvmproperties Тега нет, но значение содержится в jvmParameters атрибуте . Вы хотите добавить значение или заменить существующее custom.properties ?

2. Я хочу добавить значение -Dcustom.properties=/fs0/share/custom.properties к атрибуту jvmParameters в теге applicationServerInstance , если он не существует. В приведенном выше примере он имеет это значение, но в случае, если оно не существует, я хотел добавить это -значение Dcustom.properties=/fs0/share/custom.properties .

3. Вы могли бы взглянуть на xmlstarlet для обработки XML из командной строки.

4. Но что, если custom.properties присутствуют, но с другим значением?

5. Нет возможности иметь другое значение в -Dcustom.propertie

Ответ №1:

В вашем XML-файле первый тег applicationServerInstance имеет параметры jvmParameters со значением -Dcustom.properties=/fs0/share/custom.properties. Но во втором теге applicationServerInstance параметр jvmParameter имеет значение -Dcustom.properties=/fs0/clarity1/share/custom.properties вместо -Dcustom.properties=/fs0/share/custom.properties. В этом случае мой фрагмент кода добавляет еще одно значение Dcustom.properties.

Таким образом, второй тег applicationServerInstance будет выглядеть следующим образом.

 <applicationServerInstance id="app" serviceName=" App Server" rmiPort="15001" jvmParameters="-Xmx3072m -Xms512m -XX:-UseGCOverheadLimit -XX:MaxPermSize=196m -Dsun.lang.ClassLoader.allowArraySyntax=true -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/fs0/clarity1/clarity/logs -Xloggc:/fs0/clarity1/clarity/logs/app_gc.log -XX: PrintGCDetails -XX: PrintGCTimeStamps -XX: PrintHeapAtGC -Dcustom.properties=/fs0/clarity1/share/custom.properties -Dcustom.properties=/fs0/share/custom.properties" maxThreads="1000" programParameters="" distributed="false" runJobScheduler="false" useSSO="true" maxConcurrentJobs="10" runProcessEngine="false" messageTimeToLive="120" messageReceiverInterval="5" exceptionRunInterval="normal" maxXmlNodesLimit="150000"/>
  

Скрипт Bash:

 #!/usr/bin/env bash

file_name="/home/selvam/Scripts/test.xml"
for i in $(grep -nE "<applicationServerInstance.*jvmParameters" $file_name | cut -d ':' -f1)
do
    jvm_parameters=$(head -$i $file_name | tail -1 | awk -F '"' '{ for (c=1; c<=NF; c  ) if ($c ~ /jvmParameters/) print $(c 1)}')
    echo $jvm_parameters | grep -q 'Dcustom.properties=/fs0/share/custom.properties'
    if ([ $? -ne 0 ]) then
        jvm_new_parameters=$(echo $jvm_parameters -Dcustom.properties=/fs0/share/custom.properties)
        sed -i "${i}s%jvmParameters="$jvm_parameters"%jvmParameters="$jvm_new_parameters"%" $file_name
    fi
done
  

Ответ №2:

AWK

 awk -F"jvmParameters=" '{if((/applicationServerInstance/)amp;amp;($2!~/Dcustom.properties/)){sub("PrintHeapAtGC","PrintHeapAtGC -Dcustom.properties=/fs0/share/custom.properties")}print}' $inputfile
  

Было бы еще одно решение. Замените $inputfile именем файла, который вы хотите обработать.