I asked this question before但是我认为根据给出的答案我没有真正解释它。
我有一个名为backup.xml
的文件是28,000行,其中包含短语***
766次。我还有一个名为list.txt
的文件,其中包含766行,每行包含不同的关键字。
我基本上需要做的是将list.txt
中的每一行插入backup.xml
以替换所提到的766个地点***
。
以下是list.txt
中包含的内容的示例:
Anaheim
Anchorage
Ann Arbor
Antioch
Apple Valley
Appleton
以下是来自***
的{{1}}其中一行的示例:
backup.xml
因此,例如,根据上面的示例,应该将提到<title>*** Hosting Services - Company Review</title>
的第一行更改为:
***
非常感谢任何帮助。提前谢谢!
答案 0 :(得分:1)
在这种情况下,您可以将XML视为纯文本。 因此,请阅读XML文件,并使用从关键字文件中读取的行替换每个标记:
#!/usr/bin/perl
use strict;
use warnings;
use autodie qw( open);
my $xml_file = 'backup.xml';
my $list_file = 'list.txt';
my $out_file = 'out.xml';
my $pattern='***';
# I assumed all files are utf8 encoded
open( my $xml, '<:utf8', $xml_file );
open( my $list, '<:utf8', $list_file );
open( my $out, '>:utf8', $out_file );
while( <$xml>)
{ s{\Q$pattern\E}{my $kw= <$list>; chomp $kw; $kw}eg;
print {$out} $_;
}
rename $out_file, $xml_file;
答案 1 :(得分:0)
这个怎么样:
awk '{print NR-1 ",/\\*\\*\\*/{s/\\*\\*\\*/" $0 "/}"}' list.txt > list.sed
sed -f list.sed backup.xml
第一行使用awk
根据列表创建搜索/替换命令列表,然后通过sed
在下一行执行。
答案 2 :(得分:0)
使用awk
。它读取backup.xml
文件,当找到***
文本时,我从list.txt
文件中提取一个单词。 BEGIN
块从参数列表中删除list.txt
以避免其处理。参数的顺序非常重要。另外我假设每行只有一个***
字符串。
awk '
BEGIN { listfile = ARGV[2]; --ARGC }
/\*\*\*/ {
getline word <listfile
sub( /\*\*\*/, word )
}
1 ## same as { print }
' backup.xml list.txt
答案 3 :(得分:0)
如果两个文件顺序对应,您可以使用paste
命令连接两个文件中的行,然后进行后处理。
paste list.txt backup.xml |
awk 'BEGIN {FS="\t"} {sub(/\*\*\*/, $1); print substr($0, length($1)+2)}'
paste命令将产生以下内容:
Anaheim \t <title>*** Hosting Services - Company Review</title>
虽然AWK中的单行将用第一个字段替换***,然后删除第一个字段和字段分隔符(\ t)。
另一个变体是:
paste list.txt backup.xml |
awk 'BEGIN {FS="\t"} {sub(/\*\*\*/, $1); print $0}' |
cut -f 2-