2

我之前问过这个问题,但不认为我真的根据给出的答案正确解释了它。

我有一个名为backup.xml28,000 行的文件,其中包含该短语***766 次。我还有一个名为的文件list.txt,其中包含 766 行,每行都有不同的关键字。

我基本上需要做的是插入每一行 from list.txtintobackup.xml以替换***提到的 766 个位置。

下面是一个示例,其中包含的内容list.txt

Anaheim
Anchorage
Ann Arbor
Antioch
Apple Valley
Appleton

***这是其中来自的行之一的示例backup.xml

<title>*** Hosting Services - Company Review</title>

因此,例如,***根据上面的示例,应该将提到的第一行更改为:

<title>Anaheim Hosting Services - Company Review</title>

任何帮助将不胜感激。提前致谢!

4

4 回答 4

2

在这种情况下,您可能可以将 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;
于 2013-05-24T07:44:25.867 回答
0

使用awk. 它读取backup.xml文件,当找到一个***文本时,我从文件中提取一个单词list.txt。该BEGINlist.txt从参数列表中删除以避免其处理。参数的顺序非常重要。另外我假设***每行只有一个字符串。

awk '
        BEGIN { listfile = ARGV[2]; --ARGC }
        /\*\*\*/ {
                getline word <listfile
                sub( /\*\*\*/, word )
        }
        1     ## same as { print }
' backup.xml list.txt
于 2013-05-24T07:49:35.600 回答
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-
于 2013-05-24T09:30:20.967 回答
0

这个怎么样:

awk '{print NR-1 ",/\\*\\*\\*/{s/\\*\\*\\*/" $0 "/}"}' list.txt > list.sed
sed -f list.sed backup.xml

第一行用于awk根据列表创建搜索/替换命令列表,然后在下一行通过sed.

于 2013-05-24T07:42:04.863 回答