BASH脚本将XML文件重命名为属性值

时间:2015-07-30 08:25:23

标签: regex xml bash file

我有 很多 .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命令一起使用。

3 个答案:

答案 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

遍历xml文件
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。但上面的代码应该值得一试。