我在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脚本吗?
答案 0 :(得分:0)
这将吐出命令进行排序和分类,只提供函数/脚本/为first
,middle
,last
或{的文件做正确的事情。 {1}}在一个组中。 only
和first
命令必须处理空参数列表,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