从另一个文件的列表中替换文件中的文本?

时间:2013-05-24 07:23:36

标签: perl shell command-line command

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> 的第一行更改为:

***

非常感谢任何帮助。提前谢谢!

4 个答案:

答案 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-