Count количество элементов xml из оболочки linux
Мой xml выглядит примерно так:
<elements>
<elem>
....bunch of other elements
</elem>
</elements>
Есть ли способ подсчитать количество событий тега elem
в каком-либо файле xml через linux-оболочку? как с perl/python или что-нибудь, что может работать как один лайнер?
Я могу попробовать что-то вроде grep -c "elem" myfile.xml
, и число, которое я получаю, делят на 2
и получаю число, есть ли что-то подобное, но одно liner?
EDIT:
Я ищу альтернативное решение grep
Ответы
Ответ 1
@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 />
или с дополнительными атрибутами.
Ответ 2
Инструмент xml_grep
делает то, что вы хотите - попробуйте следующее:
xml_grep --count //elem example.xml
Эта утилита находится в пакете xml-twig-tools
на Debian/Ubuntu, а здесь находится здесь.
Ответ 3
Вы также можете использовать xmllint
:
xmllint --xpath "count(//elem)" myfile.xml
Ответ 4
НЕ ИСПОЛЬЗУЙТЕ РЕГУЛЯРНЫЕ ЭКСПРЕССИИ ДЛЯ ФАЙЛОВ XML/ФАЙЛОВ PARSE ИЛИ SCAN
Обязательное выражение об отказе от ответственности, здесь мое решение:
xmllint --nocdata --format myfile.xml | grep -c '</elem>'
xmllint
является частью libxml, что довольно часто встречается во многих дистрибутивах linux. Это решение передает следующие ловушки regex/XML:
- ложные пространства (-формат)
- несколько закрывающих тегов на одной строке (-формат)
- разделы CDATA (--nocdata)
Однако вы будете пойманы противным объявлением пространства имен и значениями по умолчанию.
Ответ 5
Лондон,
Попробуйте fgrep -c '</elem>' $filename
fgrep
- стандартная утилита unix, но не уверен в Linux. Коммутатор -c
означает подсчет.
Приветствия. Кит.
PS: все самое удобное для подсчета меток CLOSING, потому что у них нет атрибутов; -)
Ответ 6
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