任何人都可以帮我找到使用awk或sed的xml标签出现次数

时间:2011-12-22 01:39:44

标签: shell sed awk

我必须编写一个脚本,使用shell脚本计算xml文件中xml标记的数量(比如Code)。 XML文件可以是以下格式之一:

Format #1: 
<Code>value1</Code> <Code>value2</Code>

 Format #2: 
<Code Attr1=va>value1</Code> <Code Attr1=va
Attr2=va>value1</Code>

Format #3: 
<Code>value1</Code><Code>value2</Code> (All Codes can be in
a single line or multiple lines)

Format #4 
   <Code Attr1=va>value1</Code><Code Attr2=va>value1</Code>

Format #5: 
<Cod 
e>Value1</Code
<Code Attr=1> </C
ode>

简而言之,XML文件可以采用任何格式,并且可以在任何地方使用新行。 请帮助我,我需要尽快这样做..

提前致谢。

5 个答案:

答案 0 :(得分:0)

根据需要通过DOMParser或XMLDOM将XML加载到文档树中。然后使用jQuery $(xml).find(“code”)返回一个出现数组。数组的长度为您提供计数。

答案 1 :(得分:0)

正则表达式是解析XML的一种不好的方法,使用某种XML解析器更好。

如果你真的想使用sed / awk / shell / grep等,我能想到的第一件事就是:

 cat tst | xargs | grep -o '<\s*C\s*o\s*d\s*e[^>]*>' | wc -l

我不太了解awk,但我确信那里有一些awk忍者可以比这更优雅地做到这一点。

它只计算<Code>(和变体)的出现次数,但不计算结束标记,因此如果您的文件中有(例如)10 <Code>但只有9 </Code>,它将返回10而不是9。

基本上:

  • cat tst | xargs猫在一条线上的所有东西(所以我不必担心新线);
  • grep -o '<\s*C\s*o\s*d\s*e[^>]*>'打印<Code{optional other stuff}>的所有匹配项,您可以在Code的所有字母之间添加换行符/空格(-o打印 匹配正则表达式,每行一个);
  • wc -l统计线条。

连续尝试每一位,看看我的意思。

对我而言tst只是上面所用内容的复制粘贴。

[foo@bar ~]$cat tst
Format #1: 
<Code>value1</Code> <Code>value2</Code>

 Format #2: 
<Code Attr1=va>value1</Code> <Code Attr1=va
Attr2=va>value1</Code>

Format #3: 
<Code>value1</Code><Code>value2</Code> (All Codes can be in
a single line or multiple lines)

Format #4 
   <Code Attr1=va>value1</Code><Code Attr2=va>value1</Code>

Format #5: 
<Cod 
e>Value1</Code
<Code Attr=1> </C
ode>

[foo@bar ~]$cat tst | xargs
Format #1: <Code>value1</Code> <Code>value2</Code> Format #2: <Code Attr1=va>value1</Code> <Code Attr1=va Attr2=va>value1</Code> Format #3: <Code>value1</Code><Code>value2</Code> (All Codes can be in a single line or multiple lines) Format #4 <Code Attr1=va>value1</Code><Code Attr2=va>value1</Code> Format #5: <Cod e>Value1</Code <Code Attr=1> </C ode>

[foo@bar ~]$cat tst | xargs | grep -o '<\s*C\s*o\s*d\s*e[^>]*>'
<Code>
<Code>
<Code Attr1=va>
<Code Attr1=va Attr2=va>
<Code>
<Code>
<Code Attr1=va>
<Code Attr2=va>
<Cod e>
<Code Attr=1>

[foo@bar ~]$cat tst | xargs | grep -o '<\s*C\s*o\s*d\s*e[^>]*>' | wc -l
10

答案 2 :(得分:0)

快速而肮脏的方式:

由于xml文件具有不同类型的标记,因此这是一种快速而简单的方法来获取文件中xml标记的近似值。

awk -v FS="" '
BEGIN{rc=lc=0} 
{for (i=1;i<=NF;i++) if ($i~/</) {lc++} else if ($i~/>/) {rc++}}
END{print "< = "lc " and > = "rc}' xmlfile

示例文件:

[jaypal:~/Temp] cat xmlfile
Format #1: 
<Code>value1</Code> <Code>value2</Code>

 Format #2: 
<Code Attr1=va>value1</Code> <Code Attr1=va
Attr2=va>value1</Code>

Format #3: 
<Code>value1</Code><Code>value2</Code> (All Codes can be in
a single line or multiple lines)

Format #4 
   <Code Attr1=va>value1</Code><Code Attr2=va>value1</Code>

Format #5: 
<Cod 
e>Value1</Code>
<Code Attr=1> </C
ode>

执行:

[jaypal:~/Temp] awk -v FS="" '
    BEGIN{rc=lc=0} 
    {for (i=1;i<=NF;i++) if ($i~/</) {lc++} else if ($i~/>/) {rc++}}
    END{print "< = "lc " and > = "rc}' xmlfile
< = 20 and > = 20

我们现在知道有20 * <20 * >。因此,您可以得到文件中有10个xml标记的近似值,<code></code>生成1个标记。

我之所以将其作为近似值,是因为您的文件中可能有><,这可能不是xml-tag的一部分。这可能是一个开始,当然不是最终解决方案。

答案 3 :(得分:0)

这可能(?)适合你:

sed -n ':a;N;$!ba;s/\n//g;s/<\s*\/[[:alpha:]][[:alnum:]_-]*\s*>/\n&\n/gp' example |
sed -n 's/^<\//</p' | 
sort | 
uniq -c
9 <Code>

如果您有更多异国元素名称,则需要将[[:alpha:]][[:alnum:]_-]*修改为任何内容。

答案 4 :(得分:0)

如果 XML gawk 是一个选项:

xmlgawk -lxml 'END { print c }
XMLSTARTELEM == "Code" { c++ }
  ' input.xml