我的情况是我有一个文件,其内容看起来像这样但更长。https://pastebin.com/q33wFdAX
我需要删除每次出现
<category>Games</category>
</game>
如果类别中有数据,我们不想删除它。所以基本上,如果我可以像 grep -v 一样精确匹配这个双行并反转,那么我可以输出到一个没有这些行的新文件。
我将拥有的不仅仅是这个类别,所以我需要能够使用几个 or 语句。我在记事本++中使用的正则表达式示例手动完成此操作
(^\s+<category>Games</category>\s+</game>$|^\s+<category>Applications</category>\s+</game>$)
如果您也可以在 powershell 中为我提供一种简单的方法来执行此操作,则可以加分,我希望能够在任一操作系统上执行此操作。我不太擅长高级正则表达式、awk 等。
由于在原来的文件,下面将删除不提及所有冠军(USA)
的称号的rom
节点的name
属性:
xmlstarlet ed -d '//game[not(contains(rom/@name, "(USA)"))]' file-orig.xml >file-new.xml
XPath 表达式//game[not(contains(rom/@name, "(USA)"))]
选择game
具有至少一个rom
子节点的所有节点,该子节点的name
属性不包含字符串(USA)
。选择这些进行删除。
使用命令行上的重定向将输出写入新文件。
看了一会儿 XML 数据后,我注意到不是查看rom
节点,而是查看主game
节点的name
属性似乎就足够了:
xmlstarlet ed -d '//game[not(contains(@name, "(USA)"))]' file-orig.xml >file-new.xml
这将删除所有不包含(USA)
在节点name
属性中的游戏game
。
删除所有非(USA)
标题后,我下载的文件将包含 1979 个标题。
要额外过滤掉所有非Games
类别:
xmlstarlet ed \
-d '//game[not(contains(@name, "(USA)"))]' \
-d '//game[category != "Games"]' file-orig.xml >file-new.xml
剩下 1474 个游戏。
只是为了好玩,按总大小对游戏标题进行排序:
xmlstarlet ed \
-d '//game[not(contains(@name, "(USA)"))]' \
-d '//game[category != "Games"]' file-orig.xml |
xmlstarlet sel -t -m '//game' \
-v 'sum(rom/@size)' -o ' ' -v '@name' -nl | sort -n
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句