Вы можете использовать оператор диапазона sed для решения своего сценария, но перед этим убедитесь, что тег и антитег в одних и тех же строках обрабатываются. Также не будут обрабатываться несколько тегов в одной строке.
sed -e '
s/^[[:blank:]]*//
\|<instruction>.*</instruction>|b
\|<instruction>|,\|</instruction>|!b
H;\|</instruction>|!d
s/.*//;x;s/\n[[:blank:]]*//g;s/^\n//
' input_xml_lookalike_file
Для извлечения, например, значения узла value
sub -каждого узла instruction
, который также имеет узел name
sub -, значение которого равно Exterior Color
, с использованием XMLStarlet:
xmlstarlet sel -v '//instruction[name = "Exterior Color"]/value' -nl file.xml
Учитывая файл
<?xml version="1.0"?>
<AssemblyHistory>
<routing>
<instruction>
<name>Interior Finish</name>
<value>WHITE</value>
<type>0</type>
</instruction>
<instruction>
<name>Exterior Color</name>
<value>WHITE</value>
<type>0</type>
</instruction>
<instruction>
<name>Base Vinyl Color</name>
<value>WHITE</value>
<type>0</type>
</instruction>
</routing>
<phantom>False</phantom>
</AssemblyHistory>
Это вернет строку WHITE
.
Следующее будет возвращать каждый name
, который соответствует значению WHITE
во всех instruction
узлах:
xmlstarlet sel -t -v '//instruction[value = "WHITE"]/name' -nl file.xml
это почти работает:
awk 'BEGIN {RS="<instruction>"; FS="\n"; OFS=""} NR>1 {$1=RS; NF--; print}'
но он пропускает предыдущие строки и не прекращает объединение, когда видит тег /instruction
input:
LINE 0
LINE 1
LINE 2
<instruction>
<name>Glass SQFT</name>
<value>7.02</value>
<type>0</type>
</instruction>
LINE 3
output:
<instruction><name>Glass SQFT</name><value>7.02</value><type>0</type></instruction>LINE 3