命令行在名称的一部分和文件的一部分中组合更改文件

时间:2013-09-24 17:32:01

标签: bash

我在AIX上,使用bash,我们目前无法安装其他软件,因此我非常有限于命令行批处理和自定义java脚本。所以,我在不同的目录中有大量的XML文件。以下是子集的外观。

root_dir
   Pages
      PAGES_1.XML
   Queries
      QUERIES_1.XML
      QUERIES_2.XML
      QUERIES_3.XML

我已经整理了一个脚本,几乎可以获得我想要的所有内容,但如果可能的话,我不知道如何在批处理脚本中完成拼图的最后一部分。我在root下创建一个新目录,将所有XML文件复制到新目录中,然后重命名它们以删除任何空格(如果名称中有任何空格),并缓冲整数以便它们可以按字母/数字顺序排序。新输出如下所示:

copy_dir
    PAGES_001.XML
    QUERIES_001.XML
    QUERIES_002.XML
    QUERIES_003.XML

我快到了。最后一部分是这些单独的XML文件需要组合成每种类型的一个XML文件,因此需要组合HISTORY_001.XML到HISTORY_099.XML,然后需要组合QUERIES_001.XML到QUERIES_099.XML,但只能在文件中的特定点。我有一个正则表达式的文件,将选择我想要的部分,现在我只需要弄清楚如何循环每个文件子集。也许我跳过枪并且应该在移动之前完成它,但假设它们都在一个目录中,我该怎么办?

以下是数据示例。所有XML文件都带有这些相同类型的信息。

<?xml version="1.0"?>
<project name="">
  <rundate></rundate>
  <object_type code="false" firstitem="1" id="5" items="65" name="Pages">
    <primary_key>Page Name</primary_key>
    <secondary_key>Language Code</secondary_key>
    <secondary_key>Page Field ID</secondary_key>
    <secondary_key>Field Type</secondary_key>
    <secondary_key>Record (Table) Name</secondary_key>
    <secondary_key>Field Name</secondary_key>
    <item id="ACCTG_TEMPLATE_AP">
      ...
    </item>
    <item id="ACCTG_TEMPLATE_AR">
      ...
    </item>
  </object_type>
</project>

查询

<?xml version="1.0"?>
<project name="">
  <rundate></rundate>
  <object_type code="false" firstitem="1" id="10" items="46" name="Queries">
    <primary_key>Query Name</primary_key>
    <primary_key>User ID</primary_key>
    <item id="1099G_ALL_SHORT. ">
      ...
    </item>
    <item id="1099G_ALL_VOUCHERS. ">
      ...
    </item>
  </object_type>
</project>

正则表达式拔出标题

(?:(?!(^\s*i<item)).)*

正则表达式提取细节

^(\s*<item id=).*(</item>)

正则表达式拉出页脚

^(\s*</object_type).*

所以我假设我想做的事情有一个计数器,循环遍历每个对象类型的XML子集,如果我是第一个循环然后拉出标题和细节并输出到新的摘要文件,然后继续所有其他文件用于连接细节,然后如果是最后一个文件或更改为新的对象类型,那么也输出页脚。你认为这可以使用bash脚本吗?

2 个答案:

答案 0 :(得分:0)

这将吐出命令进行排序和分类,只提供函数/脚本/为firstmiddlelast或{的文件做正确的事情。 {1}}在一个组中。 onlyfirst命令必须处理空参数列表,middle表示两个元素组,middle表示没有first - 序列文件的组。 / p>

编辑:我将seds打破了每行一个命令来处理不喜欢分号的seds

以此为例运行1

sh this.sh *_*.*

上述#!/bin/sh # # spit commands to sort, group, and classify argument filenames # sorting by the number between `_` and `.` in their names and # grouping by the text before the _. { # Everything through the sort would just be `ls -v` on GNU/anything... for f; do pfx=${f%%_*} tail=${f#*_} sortable=`printf %s_%03d.%s $pfx ${tail%.*} ${tail##*.}` [ $f != $sortable ] \ && echo mv $f $sortable >&2 echo $sortable done \ | sort \ | sed ' /_0*1\./! H // { x 1! { y/\n/ / p } } $!d x y/\n/ / ' \ | sed ' s/\([^ ]*\)\(.*\) \(.*\)/first \1\nmiddle\2\nlast \3/ t s/^/only / ' } 2>&1 中的第一个累积了每行一个字的组,可以通过它们的第一行识别。第二个对右侧命令中的组和子进行分类。它们是分开的,因为第一个sed涉及一个双泵来处理一个寡妇组,而且它们的毛茸茸就像它一样。

答案 1 :(得分:0)

combine()
{
    # pull the header from 1st file
    while IFS= read && word=($REPLY) && [ "$word" != "<item" ]
    do  echo "$REPLY"
    done <$1

    # concat the detail from all files
    for file
    do  cmd=:
        while IFS= read && word=($REPLY)
        do  case $word in \<item) cmd=echo;; esac
            $cmd "$REPLY"
            case $word in \</item\>) cmd=:;; esac
        done <$file
    done

    # output the footer
    while IFS= read && word=($REPLY)
    do  case $word in \</object_type\>) cmd=echo;; esac
        $cmd "$REPLY"
    done <$file
}

combine PAGES_???.XML >PAGES.XML
combine QUERIES_???.XML >QUERIES.XML