如何根据某些文件订购字符串

时间:2017-05-22 13:18:27

标签: linux bash unix

<scene name="scene_1_Overview" title="1 Overview" onstart="" thumburl="panos/1_Overview.tiles/thumb.jpg" lat="" lng="" heading="">
    abc
</scene>

<scene name="scene_1_Overview" title="10 Overview" onstart="" thumburl="panos/1_Overview.tiles/thumb.jpg" lat="" lng="" heading="">
    abc
</scene>

<scene name="scene_10_Room_Balcony_View" title="2 Room Balcony View" onstart="" thumburl="panos/10_Room_Balcony_View.tiles/thumb.jpg" lat="" lng="" heading="">

    abc
    def
</scene>

说我有如上所述的XML文件 现在我需要根据title=后跟的数字按顺序排列三个元素,分别为1,10和2.

我正在考虑使用bash脚本来执行此操作 我可以使用awk '{print $3}' test | awk -F "\"" '{print $2}'之类的内容来获取三个数字,但我不知道如何从每个<scene</scene>读取多行,以便按顺序排列并覆盖它们。< / p>

2 个答案:

答案 0 :(得分:0)

使用xsltproc

$ xsltproc sort.xslt scenes.xml

sort.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:sort select="scene/@title" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

否则以下perl one-liner

perl -e '
    undef$/;
    print "$_\n" for sort{
        ($a=~/title="(.*?)"/ms)[0] cmp ($b=~/title="(.*?)"/ms)[0]
    }<>=~/<scene[ >].*?<\/scene>/gms
' scenes.xml

答案 1 :(得分:0)

我认为在awk中这样做并不是最好的主意,但我知道它被困在一个你无法安装任何东西的盒子上。如果你坚持使用它,那么像下面的awk脚本应该让你进入球场。

 awk -F"[\" ]" '$0~/title/{title=$6} {scene[title]=scene[title]$0"\n"} END{PROCINFO["sorted_in"]="@ind_num_asc"; for (title in scene) {print scene[title]}}' inFile

这里awk是:

  1. "-F"[\" ]"
  2. 拆分每一行
  3. 如果该行包含单词"title"$0~/title/),则它会将变量title设置为在字段6(title=$6;)中找到的任何内容,如果你的名字&#34;包含空格,因为我们正在分裂,所以你可能不得不使用分隔符。
  4. 接下来,它将该行的内容以及换行符存储到由scenestitle
  5. 中存储的数字设置的索引处的数组{scene[title]=scene[title]$0"\n"}
  6. 处理完文件后,它将PROCINFO["sorted_in"]设置为@ind_num_asc,告诉awk使用索引循环遍历数组,同时强制索引作为数字{{ 1}})
  7. 然后我们遍历数组并打印每个元素((END{PROCINFO["sorted_in"]="@ind_num_asc"
  8. 最小化一点:

    for (title in scene) {print scene[title]}