我有几千个以下模板的(格式良好的) 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
- cat xml 文件
- 使用 egrep 删除不需要的行
- 根据示例“语句名称”将输入拆分为多个文件
- 循环结果
- 计算每个文件的行数,并要求其大于 10
- 打印输出文件名
- 打印输出行
正如我所说,这并不是一个通用的 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