查找具有特定值的 XML 文件

查找具有特定值的 XML 文件

我有一个包含约 10K XML 文件的文件夹。他们每个人看起来都是这样的:

...
<object>
<name>Cat</name>
</object>
<object>
<name>Cow</name>
</object>
...

包括name人、猫、狗、牛……我想挑选出唯一带有猫和/或狗的 xml 文件。我怎样才能做到这一点?

答案1

要从像您这样的 XML 文档中的节点中获取所有Cator值,您可以像这样使用:Dognamexmlstarlet

xmlstarlet sel -t -v '//object/name[text() = "Cat" or text() = "Dog"]' file.xml

如果文档中存在单词 和 作为节点子节点的值,则这将生成单词Cat和作为输出。如果存在其他节点不是节点的子节点,或者某些节点具有属性等,则此操作将很难正确执行。Dogobjectnamegrepnameobjectname

不幸的是,xmlstarlet如果在 XML 输入文件中找不到任何内容,则不会以非零退出状态退出,因此我们需要grep在末尾添加 a 来检查是否有任何输出(这将是在下一步中使用):

xmlstarlet sel -t -v '//object/name[text() = "Cat" or text() = "Dog"]' file.xml | grep '.'

然后我们可以在所有 10k 个文件上运行它find

find . -type f -name '*.xml' -exec sh -c '
    xmlstarlet sel -t -v "//object/name[text() = \"Cat\" or text() = \"Dog\"]" "$1" |
    grep -q "."' sh {} ';' -print

这将首先找到当前目录中或当前目录下名称以.xml.对于每个这样的文件,xmlstarlet运行以从正确的 XML 节点中提取Cat和字符串,并用于检查是否找到任何内容。使用其选项运行会使实用程序安静,但它将以适当的退出状态退出,具体取决于它是否匹配任何内容。Doggrepxmlstarletgrep-q

如果grep找到任何内容,find则打印包含该数据的文件的路径名。

答案2

以下代码基于GNU grep

正如你所说,所有文件都是这样,所以你可以使用 grep

对于猫或狗,使用

grep -l '<name>\(Cat\|Dog\)</name>' *

如果猫和狗都在场,请使用

grep -l '<name>Cat</name>' * | xargs grep -l '<name>Dog</name>'

如果您想要不区分大小写的搜索,请-i向 grep 添加选项

-l- 此选项将仅打印匹配的文件名

使用普通的正则表达式,字符(,|)需要转义,所以我已经转义了它们

答案3

如果你有许多文件考虑使用索引器工具,如 Beagle、Tracker、glick 或类似工具。

例子:

$ glimpseindex -H .  MyDir
$ glimpse -l  -H .  'cat;dog'     

获取包含cad和dog的文件

相关内容