我有 很多 的.xml
个文件以相同的方式构建:
<parent id="idvalue" attr1="val1" attr2="val2" ...>
<child attr3="val3" attr4="val4" ... />
<child attr3="val5" attr4="val6" ... />
...
</parent>
每个文件只有一个<parent>
元素,只有一个id
属性。
所有这些文件(大约1,700,000个)都被命名为part.xxxxx,其中xxxxx是一个随机数。
我想根据文件内容中唯一的idvalue.xml
属性,将每个文件命名为id
。
我相信使用bash脚本执行此操作将是最快且最自动化的方式。但如果有其他建议,我很乐意听到。
我的主要问题是我无法(不知道如何)在特定文件中获取idvalue
,因此我可以将其与mv file.xxxxx idvalue.xml
命令一起使用。
答案 0 :(得分:2)
使用适当的XML处理工具从文件中提取id。例如, xsh:
for file in part.* ; do
mv "$file" $(xsh -aC 'open { shift }; echo /parent/@id' "$file").xml
done
答案 1 :(得分:2)
首先,我将使用find
:
find -maxdepth 1 -name 'part*.xml' -exec ./rename_xml.sh {} \;
上面的行将为每个xml文件执行rename_xml.sh
,将文件名作为命令参数传递给脚本。
rename_xml.sh
应如下所示:
#!/bin/bash
// Get the id using XPath. You might probably need
// to install xmllint for that if it is not already present.
// The xpath query will return a string like this (try it!):
//
// id="idvalue"
//
// We are using sed to extract the value from that
id=$(xmllint --xpath '//parent/@id' "$1" | sed -r 's/[^"]+"([^"]+).*/\1/')
mv -v "$1" "$id.xml"
别忘了
chmod +x rename_xml.sh
答案 2 :(得分:1)
就像我在评论中提到的那样,与bash脚本相比,我不确定XSLT的性能,但我创建了XSLT供你试用。
在下面的样式表中,Dire是包含xml文件的目录。选择“tokenize(document-uri(。),'/')[last()]” 检索文件名,第二行连接目录名和文件名以获取文件的路径。使用xsl:copy..is来复制整个xml。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt" xmlns:random="http://www.microsoft.com/msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="collection('Dire/?select=*.xml')" >
<xsl:variable name="filename" select="tokenize(document-uri(.), '/')[last()]"/>
<xsl:variable name="filepath" select="concat('Dire/',$filename)"/>
<xsl:variable name="doc" select="document($filepath)"/>
<xsl:variable name="outname" select="$doc/parent/@id"/>
<xsl:result-document href="{$outname}.xml" method="xml">
<xsl:copy-of select="$doc/node()"/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我使用saxon8运行xslt。不幸的是我找不到任何方法直接重命名xml。但上面的代码应该值得一试。