1

我有一个带有一堆数据库表定义的大型 xml 文件,如下所示:

table name="dbname.tablename" lots of text here>

我想替换每个匹配行中的结束括号(并非所有行都以 开头table name=""),以便保留原始行,但slonyId="number">. 为了让事情更复杂一点,我希望 slonyId 数字从 0 开始递增,这样如果我有 1000 个表定义,第一个看起来像:

table name="dbname.tablename" lots of text here slonyid="0">

最后一个看起来像:

table name="dbname.tablename" lots of text here slonyId="999">

解决这个问题的最佳方法是什么?

提前致谢!

4

5 回答 5

3

从 JS 添加解决方案:

awk -F'>' '/table name/{$NF="slonyid="q x++ q FS}1' q='"' inputFile

尝试这个:

awk -F'>' '/table name/{print $(NF-1)" slonyid""=""\""NR-1"\""">"}' inputFile

添加测试:

$ cat temp.txt
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>
table name="dbname.tablename" lots of text here>


$ awk -F'>' '/table name/{print $(NF-1)" slonyid""=""\""NR-1"\""">"}' temp.txt
table name="dbname.tablename" lots of text here slonyid="0">
table name="dbname.tablename" lots of text here slonyid="1">
table name="dbname.tablename" lots of text here slonyid="2">
table name="dbname.tablename" lots of text here slonyid="3">
table name="dbname.tablename" lots of text here slonyid="4">
table name="dbname.tablename" lots of text here slonyid="5">
table name="dbname.tablename" lots of text here slonyid="6">
table name="dbname.tablename" lots of text here slonyid="7">
table name="dbname.tablename" lots of text here slonyid="8">
table name="dbname.tablename" lots of text here slonyid="9">
table name="dbname.tablename" lots of text here slonyid="10">
table name="dbname.tablename" lots of text here slonyid="11">
table name="dbname.tablename" lots of text here slonyid="12">
table name="dbname.tablename" lots of text here slonyid="13">
table name="dbname.tablename" lots of text here slonyid="14">
于 2013-06-29T03:47:34.767 回答
2

GNU 的代码:

sed = file|sed 'N;s/\n/\t/;/\S\+\s\+table name/!d'|sed =|sed 'N;s/\n/\t/;s/\(\S\+\)\s\+\([^>]\+\)>/\2 slonyid="\1">/;s#\(\S\+\)\s\+\(.*\)#\1 s/.*/\2/#'|sed -f - file

sed带有 4 根管道的纯溶液。

$猫文件
table name="dbname.tablename" 这里有很多文字 AAA>
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
index name="dbname.tablename" 这里有很多文字 ZZZ>
table name="dbname.tablename" 这里有很多文字BBB>
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
table name="dbname.tablename" 这里有很多文字 CCC>
index name="dbname.tablename" 这里有很多文本 XXX>
table name="dbname.tablename" 这里有很多文字 DDD>
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
index name="dbname.tablename" 这里有很多文字 ZZZ>
table name="dbname.tablename" 这里有很多文本 EEE>
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
table name="dbname.tablename" 这里有很多文本 FFF>
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
index name="dbname.tablename" 这里有很多文字 ZZZ>

$sed = 文件|sed 'N;s/\n/\t/;/\S\+\s\+表名/!d'|sed =|sed 'N;s/\n/\t/; s/\(\S\+\)\s\+\([^>]\+\)>/\2 slonyid="\1">/;s#\(\S\+\)\s\ +\(.*\)#\1 s/.*/\2/#'|sed -f - 文件
table name="dbname.tablename" 这里有很多文字 AAA slonyid="1">
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
index name="dbname.tablename" 这里有很多文字 ZZZ>
table name="dbname.tablename" 这里有很多文本 BBB slonyid="2">
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
table name="dbname.tablename" 这里有很多文字 CCC slonyid="3">
index name="dbname.tablename" 这里有很多文本 XXX>
table name="dbname.tablename" 这里有很多文本 DDD slonyid="4">
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
index name="dbname.tablename" 这里有很多文字 ZZZ>
table name="dbname.tablename" 这里有很多文本 EEE slonyid="5">
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
table name="dbname.tablename" 这里有很多文本 FFF slonyid="6">
index name="dbname.tablename" 这里有很多文本 XXX>
index name="dbname.tablename" 这里有很多文本 YYY>
index name="dbname.tablename" 这里有很多文字 ZZZ>
于 2013-06-29T07:43:51.500 回答
1

如果我正确理解了您的问题,这个 perl 单行程序就可以解决问题:

perl -pi.bak -e 'BEGIN {$count=0}; if (/^table name=/) { s/^(table name=.*)>$/$1 slonyId="$count">/; $count++}' inputFile.xml

这些选项告诉 perl 遍历给定的文件名并创建一个名为“orig_filname.bak”的备份:

perl -pi.bak -e

这将初始化$count变量:

BEGIN {$count=0};

这会增加计数并执行您要求的替换:

if (/^table name=/) { s/^(table name=.*)>$/$1 slonyId="$count">/; $count++}

然后只需在末尾提供文件名列表:

inputFile.xml

这不是一个非常强大的解决方案,如果文件中的任何行与您上面给出的描述不匹配,它可能会中断,但它应该可以解决您的问题。

我认为我太新了,无法直接评论其他解决方案,但在我的测试中,FDinoff 的解决方案会将 slonyId 添加到如下所示的行中:

not a table name="dbname.tablename" lots of text here>

并且 Amit 的解决方案会将 slonyId 添加到每一行,而不仅仅是以“表名”开头的行。

于 2013-06-29T04:20:15.810 回答
0

vim 解决方案

使用 globaltable name=在一行中查找。并将>该行上的替换为slonyId="number">您可以使用以下两行来执行此操作。

:let i = 0
:g/^table name=/s/>/\='slonyId="' . i . '"' . submatch(0)/ | let i=i+1

第一行初始化i为 0。替换每次进行匹配时都会获取该列表的第一个元素,并使用字符串连接来生成正确的字符串。然后在替换之后i会递增。以便下一个替代者获得序列中的下一个数字。

于 2013-06-29T03:57:49.577 回答
0

您永远不应该使用逐行字符串操作来编辑 XML 文件。XML 的结构不是那样的。始终使用适当的 XML 解析器,例如 Perl 的XML::LibXML

#!/usr/bin/env perl

use strict;
use warnings;
use XML::LibXML;

my $xml = XML::LibXML->new->parse_file('/path/to/input.xml');

my $i = 0;
$_->setAttribute('slonyId', $i++) for $xml->findnodes('//table');

$xml->toFile('/path/to/output.xml')
于 2013-06-29T09:19:30.127 回答