從輸入檔案讀取資料並將資料放入 xml 中的適當欄位中

從輸入檔案讀取資料並將資料放入 xml 中的適當欄位中

我有一個輸入檔和一個 xml 檔。

輸入檔-

/user/sht
227_89,45_99
/user/sht1
230_90
/user/sht2
441_50

該檔案具有包含路徑和位置的替代行。

xml 檔案-

<aaa><command name="move">
<domain>
<path></path>
<positions></positions>
</domain>
<domain>
<path></path>
<positions></positions>
</domain>
<domain>
<path></path>
<positions></positions>
</domain>
</command>
</aaa>

我需要編寫一個腳本來提供以下所需的輸出 xml,然後使用以下 xml 作為輸入來運行一些命令-

<aaa><command name="move">
<domain>
<path>/user/sht</path>
<positions>227_89,45_99</positions>
</domain>
<domain>
<path>/user/sht1</path>
<positions>230_90</positions>
</domain>
<domain>
<path>/user/sht2</path>
<positions>441_50</positions>
</domain>
</command>
</aaa>

我嘗試從輸入檔中逐行提取並將其放入 xml 中,但問題是每次出現的<path>都會被第一個輸入行取代。

使用 GNU bash 4.1.2。

答案1

使用一個 GNUsed腳本你可以做類似的事情

sed -n '/<aaa>/,/<.aaa>/!{H;d}
G;:a
s_>\(</path>.*\n\)\n\([^\n]*\)_>\2\1_
s_>\(</positions>.*\n\)\n\([^\n]*\)_>\2\1_;
ta;P;s/.*\n\n/\n/;h' input.txt input.xml

第一行收集保留緩衝區中第一個檔案的所有行。

然後,對於第二個檔案的每一行,保留緩衝區都會附加G.如果是 a path,則positions使用兩個命令之一將保持緩衝區的第一段移動到標籤內s

在任何情況下,該行都會被列印 ( P) 並被刪除 ( s/.*\n\n/\n/),並且替換清單的剩餘內容將移回保存緩衝區以供下一個週期 ( h)。

答案2

Shell 腳本將滿足您的要求

#!/bin/bash
count=0          ## counting lines
while read var
do
    occurance=$[$count/2+1];                  ## check nth occurance of search path/position from file
if [ $((count%2)) -eq 0 ];                ## If counting even replace path values else replace position values
then
    perl -pe 's{<path>*}{++$n == '$occurance' ? "<path>'$var'" : $&}ge' xml > xml1
else
    perl -pe 's{<positions>*}{++$n == '$occurance' ? "<positions>'$var'" : $&}ge' xml > xml1
fi
yes|cp xml1 xml
    count=$[$count +1]
done <./input
rm xml1 

答案3

使用 GNU sed 和 XML 格式,如下所示:

sed -e '
   /<domain>/,/<\/domain>/!b
   /<\(path\|positions\)><\/\1>/!b
   s//<\1>/
   R input_file
' XML_file |
sed -e '
   /<\(path\|positions\)>.*/N
   s//&\n<\/\1>/
   s/\n//g
'

結果

<aaa><command name="move">
<domain>
<path>/user/sht</path>
<positions>227_89,45_99</positions>
</domain>
<domain>
<path>/user/sht1</path>
<positions>230_90</positions>
</domain>
<domain>
<path>/user/sht2</path>
<positions>441_50</positions>
</domain>
</command>
</aaa>

答案4

在外殼中:

echo '<aaa><command name="move">'
echo '<domain>'

while true
do read v || break
   echo "<path>$v</path>"
   read v || break
   echo "<positions>$v</positions>"
done < /path/to/YourInputFile

echo '</domain>
</command>
</aaa>'

相關內容