Как извлечь данные между двумя разными xml-тегами

На самом деле есть две проблемы. Первый из них очевиден, на что указали другие: lsblk перечисляет диски по устройствам, а df работает с смонтированными файловыми системами. Итак, lsblk / dev / sda3 примерно эквивалентен df -h / в вашем случае, поскольку / dev / sda3 установлен на /.

За исключением того, что это не так. Поскольку lsblk перечисляет размер раздела, а df перечисляет размер файловой системы. Разница (93,1 ГБ против 92 ГБ для sda3 в вашем примере) заключается в сочетании неиспользуемого пространства (если есть) и накладных расходов на файловую систему. Некоторое количество места необходимо для отслеживания самой файловой системы, а не содержимого файлов, которые она хранит.

2
28.02.2017, 01:36
4 ответа

, если вы хотите извлечь значение идентификатора, и я предполагаю, что идентификатор всегда является первым тегом, вы можете использовать этот

awk -F"[<>]" '{print $3}' input.txt

, если хотите найти конкретный тег, а затем попробуйте эту команду awk. вам нужно изменить значение input = ID

awk -F"[<>]" '{for(i=1;i<=NF;i++)if($i~input){print $(i+1);next}}' input=ID input.txt
-2
27.01.2020, 23:10

Grep

grep -oE '<data>[^<]*</data>' yourxmlfile

Bash

tag='data'
tL="<$tag>" tR="</$tag>"
xml=$(< yourxmlfile)
while case $xml in *"$tL"* ) :;; * ) break;; esac; do
  t1=${xml#*"$tL"} t2=${t1%%"$tR"*} xml=${t1#*"$tR"}
  echo "${tL}${t2}${tR}"
done

Perl

perl -lne "print for/<$tag>.*?<\/$tag>/g" yourxmlfile

Sed

sed -e "
  s|<$tag>|\n&|
  s/.*\n//
  s|</$tag>|&\n|
  /\n/P;D
" yourxmlfile

Вывод

 <data>asdf</data>
 <data>asdf</data>
 <data>asdf</data>
 <data>asdf</data>
-1
27.01.2020, 23:10

Как отмечалось в комментариях, ваши данные плохо -сформированы в формате XML, и не совсем ясно, какова структура вашего документа, например. судя по данным вашего примера, похоже, что у вас нет вложенных элементов -это действительно так?

С учетом этого предостережения, вот сценарий Python, который использует библиотеку синтаксического анализа BeautifulSoup4 , чтобы делать то, что вы хотите (, т. е. он создает желаемые выходные данные для данного примера входных данных):

#!/usr/bin/env python
# coding: ascii
"""extract.py

Extract everything between two XML tags
in a (possibly poorly formed) XML document."""

from bs4 import BeautifulSoup
import sys

# Set the opening tag name and value
opening_name = "ID"
opening_text = "2"

# Set the closing tag name
closing_name = "dateAccessed"

# Get the XML data from a file and instantiate a BeautifulSoup parser
# We add a root node because the input data is missing a root
with open(sys.argv[1], 'r') as xmlfile:
    xmldoc = "<root>" + xmlfile.read() + "</root>"
    soup = BeautifulSoup(xmldoc, 'xml')

# Iterate through the elements of the XML data and collect
# all of the elements inbetween the opening and closing tags
elements = []
match = False
for e in soup.find_all():
    if match is True:
        elements.append(str(e))
        if e.name==closing_name:
            break
    else:
        try:
            if e.name==opening_name and e.text==opening_text:
                match = True
                elements.append(str(e))
        except AttributeError:
            pass

# Output the results on a single line
print("".join(elements))

Вы бы запустили это как-то так:

python extract.py data.xml

Для данных вашего примера:

<ID>1</ID><data>asdf</data><data2>asdf</data2><dataX>asdf</dataX><dateAccessed>somedate</dateAccessed><ID>2</ID><data>asdf</data><data2>asdf</data2><dataX>asdf</dataX><dateAccessed>somedate</dateAccessed><ID>3</ID><data>asdf</data><data2>asdf</data2><dataX>asdf</dataX><dateAccessed>somedate</dateAccessed><ID>4</ID><data>asdf</data><data2>asdf</data2><dataX>asdf</dataX><dateAccessed>somedate</dateAccessed>

Выдает следующий результат:

<ID>2</ID><data>asdf</data><data2>asdf</data2><dataX>asdf</dataX><dateAccessed>somedate</dateAccessed>
1
27.01.2020, 23:10

Предполагая, что XML-документ действительно имеет корневой тег (, ваш XML не имеет и, следовательно, имеет неправильный формат ), тогда вы можете использовать XMLstarlet следующим образом:

xmlstarlet sel -t -m '//ID[. = 2]' \
    -c. -c './following-sibling::*[position()<5]' -nl file.xml

Для заданных данных (, измененных для вставки <root>в начале и </root>в конце ), будет возвращено

<ID>2</ID><data>asdf</data><data2>asdf</data2><dataX>asdf</dataX><dateAccessed>somedate</dateAccessed>

Запрос XMLstarlet выбирает любой IDузел с содержимым2(-m '//ID[. = 2]'). Для каждого из этих узлов (только один в заданных данных ), он возвращает копию самого узла(-c.)вместе с копией следующих пяти одноуровневых узлов (-c './following-sibling::*[position()<5]'), заканчивая вывод вставкой новой строки(-nl).

Начальный и конечный теги <root>могут быть вставлены в сам документ или переданы в XMLstarlet следующим образом:

{ echo '<root>'; cat file.xml; echo '</root>'; } |
xmlstarlet sel -t -m '//ID[. = 2]' \
    -c. -c './following-sibling::*[position()<5]' -nl
1
27.01.2020, 23:10

Теги

Похожие вопросы