количество элементов XML из оболочки Linux - PullRequest
11 голосов
/ 26 апреля 2011

Мой xml выглядит примерно так:

<elements>
<elem>
....bunch of other elements
</elem>
</elements>

Есть ли способ подсчитать количество вхождений тега elem в некоторых xml-файлах через оболочку linux? как с perl / python или чем-то, что может работать как один лайнер?

Я мог бы попробовать что-то вроде grep -c "elem" myfile.xml и число, которое я получил, разделить его на 2 и получить число, есть ли что-то похожее, но один вкладыш?

РЕДАКТИРОВАТЬ:

Я ищу альтернативное решение grep

Ответы [ 6 ]

15 голосов
/ 26 апреля 2011

Инструмент xml_grep делает то, что вы хотите - попробуйте следующее:

xml_grep --count //elem example.xml

Эта утилита находится в пакете xml-twig-tools в Debian / Ubuntu, а документация находится здесь .

7 голосов
/ 23 февраля 2016

Вы также можете использовать xmllint:

xmllint --xpath "count(//elem)" myfile.xml
2 голосов
/ 26 апреля 2011

НЕ ИСПОЛЬЗУЙТЕ РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ ДЛЯ ФОРМИРОВАНИЯ ИЛИ СКАНИРОВАНИЯ XML-ФАЙЛОВ

Обязательный отказ от ответственности, вот мое решение:

xmllint --nocdata --format myfile.xml | grep -c '</elem>'

xmllint является частью libxml , что довольно часто встречается во многих дистрибутивах Linux.Это решение передает следующие ловушки regex / XML:

  • паразитные пробелы (--format)
  • несколько закрывающих тегов в одной строке (--format)
  • CDATAсекции (--nocdata)

Тем не менее, вы попадетесь под неприятное объявление пространства имен и значения по умолчанию.

1 голос
/ 26 апреля 2011

grep само по себе не поможет во всех случаях, но это простой случай для XMLStarlet .Вы можете сопоставить elem с XMLStarlet, а затем считать новые строки с wc -l.В новых строках минус 1 - количество элементов.

Пример YOURFILE.xml:

<elements>
<elem>....bunch of other elements</elem><elem>....bunch of other elements</elem>
<elem>
....bunch of other elements
....bunch of other elements
</elem>
</elements>

Использовать XMLStarlet и wc-l:

echo $(($(xmlstarlet sel -t -m //elem -n YOURFILE.xml | wc -l)-1))

Вывод: 3

1 голос
/ 26 апреля 2011

Лондон

Попробуйте fgrep -c '</elem>' $filename

fgrep - это стандартная утилита Unix, хотя я не совсем уверен в Linux. Переключатель -c означает count .

Приветствия. Кит.

PS: Считать закрывающие теги всегда проще, поскольку они не имеют атрибутов; -)

0 голосов
/ 26 апреля 2011

@ OP, все решения grep имеют фундаментальный «недостаток» в том, что он пропустит счет, если более 1 <elem> тегов будет одним на строку. Используйте awk для программного подсчета

awk 'BEGIN{
    totalelem=0
    totalendelem=0
}
/<elem>/{
    m = split($0,a,"<elem>") # or m = gsub(/<elem>/,"")
    totalelem+=m-1
}
/<\/elem>/{
    m = split($0,b,"</elem>") # or m = gsub("</elem>","")
    totalendelem+=m-1
}
END{
    print "Total elem tags: " totalelem
    print "Total end elem tags: " totalendelem
    # if you want to make sure each elem tag is enclosed  by corresponding end elem tag
    if ( totalelem == totalendelem ){
        print "Equal start and end tags"
    }
}
' file

это решение предполагает, что вы знаете, как будут выглядеть ваши теги elem. Нет <elem /> или те с дополнительными атрибутами ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...