在一堆 XML 文件中查找多行 CDATA 文本(可能使用 grep)

在一堆 XML 文件中查找多行 CDATA 文本(可能使用 grep)

我有几千个以下模板的(格式良好的) XML 文件:

<?xml version="1.0" ?>
<queries>
  <statement name="foobar">
    <body><![CDATA[
      Several lines
      worth of
      text goes
      in here 
    ]]></body>
  </statement>
  <statement name="whatever">
    [... snip ...]
  </statement>
</queries>

我需要获取正文文本内容超过 10 行的语句列表。除了编写 Python 脚本来执行此操作外,是否有一种简单的方法可以使用 grep 或其他标准工具来查看每个文件并返回跨越多行的语句?至少,我很高兴能有一种方法可以返回包含此类语句的文件名列表。

答案1

除了使用真正的 xml 库和/或 awk/perl/python/ruby 之外,这非常接近您想要的(如果我理解正确的话),只需使用常见的 bash 命令。

请注意,这实际上特定于所使用的 xml 文件,不应被鼓励作为通用 xml 解析器/分割器。

您需要为分割后的文件设置输出目录。我在此示例中使用了 /tmp/out:

mkdir -p /tmp/out 

每次运行前你都必须清理/tmp/out。否则你将得到不合理的结果。

cat /path_to_xml_files/*.xml | \
egrep -v '<?xml version="1.0" \?>|<queries>|</queries>' | \
csplit -q -z - '/statement name/' '{*}' --prefix=/tmp/out/splitout- && \
for x in /tmp/out/splitout-* ; do \
[[ $(wc -l "$x"|cut -d" " -f 1) -gt 10 ]] && \
echo "$x" && \
cat "$x" ; \
done
  1. cat xml 文件
  2. 使用 egrep 删除不需要的行
  3. 根据示例“语句名称”将输入拆分为多个文件
  4. 循环结果
  5. 计算每个文件的行数,并要求其大于 10
  6. 打印输出文件名
  7. 打印输出行

正如我所说,这并不是一个通用的 xml 分割器,而应该被视为不同 shell 命令的示例。

注意:'\'-符号后跟换行符表示该行继续而不换行。这只是为了使其更易于阅读。

答案2

我只能使用nokogiri安装了 Gem 的 Ruby。我认为使用 grep 不会那么简单,但也许有人有更好的解决方案。语法是:

ruby scriptname.rb <directory> <number-of-lines>

例如:

ruby find.rb . 10

这将列出所有.xml文件

  • 包含statement
  • 带有CDATA文本
  • 这是body
  • 包含多<number-of-lines>行文本(>,而不是≥)

但没有异常处理。


require 'nokogiri'
dir, lines = ARGV
@result = []
Dir.glob("#{dir}/*.xml") do |entry|
  Nokogiri::XML(File.open(entry)).xpath("//statement/body").each { |b| (@result << entry and break) if b.text.lines.count > (2+lines.to_i) }
end
puts @result

相关内容