假设我有一堆XML文件,其中不包含换行符,但基本上包含一长串记录,由</record><record>
如果分隔符为</record>\n<record>
,我可以执行cat *.xml | grep xyz | wc -l
之类的操作来计算感兴趣的记录实例,因为cat会每行发出一个记录。
有没有办法写SOMETHING *.xml | grep xyz | wc -l
SOMETHING
每行可以流出一条记录?我尝试使用awk
,但无法找到避免将整个文件流式传输到内存中的方法。
希望问题很清楚:)
答案 0 :(得分:5)
这有点难看,但它有效:
sed 's|</record>|</record>\
|g' *.xml | grep xyz | wc -l
(是的,我知道我可以缩短一点,但只是以清晰为代价。)
答案 1 :(得分:2)
如果您的记录正文中没有<
或/
或>
这样的字符,那么您可以试试这个:
grep -E -o 'SEARCH_STRING[^<]*</record>' *.xml| wc -l
或
grep -E -o 'SEARCH_STRING[^/]*/record>' *.xml| wc -l
或
grep -E -o 'SEARCH_STRING[^>]*>' *.xml| wc -l
答案 2 :(得分:2)
以下是使用 xsltproc , grep 和 wc 的不同方法。警告:我是XSL的新手所以我可能很危险:-)。这是我的count_records.xsl文件:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" /> <!-- Output text, not XML -->
<xsl:template match="record"> <!-- Search for "record" node -->
<xsl:value-of select="text()"/> <!-- Output: contents of node record -->
<xsl:text> <!-- Output: a new line -->
</xsl:text>
</xsl:template>
</xsl:stylesheet>
在我的Mac上,我找到了一个名为 xsltproc 的命令行工具,该工具读取XSL文件中的指令,处理XML文件。所以命令是:
xsltproc count_records.xsl *.xml | grep SEARCH_STRING | wc -l
答案 3 :(得分:1)
您也可以尝试使用xmlstarlet
gig大小的文件:
# cf. http://niftybits.wordpress.com/2008/03/27/working-with-huge-xml-files-tools-of-the-trade/
xmlstarlet sel -T -t -v "count(//record[contains(normalize-space(text()),'xyz')])" -n *.xml |
awk '{n+=$1} END {print n}'
xmlstarlet sel -T -t -v "count(//record[contains(normalize-space(text()),'xyz')])" -n *.xml |
paste -s -d '+' /dev/stdin | bc