使用另一个文件中的字符串替换一个文件中的字符串的有效方法

时间:2012-10-30 14:51:15

标签: linux bash unix sed awk

搜索类似的问题,找不到任何符合我需求的内容:

我从多个网站上抓取了一个非常大的HTML文件,我想替换所有

class="key->from 2nd file"

style="xxxx"

目前我使用的是sed - 它效果很好但只有小文件

  读取键时

;做sed -i“s / class = \”$ key \“/ style = \”xxxx \“/ g”   file_to_process;完成<键

当我试图处理更大的东西时需要很长时间

示例:

keys - Count: 1233 lines
file_to_ process - Count: 1946 lines

完成我需要的1/10处理需要大约40秒

real    0m40.901s
user    0m8.181s
sys     0m15.253s

5 个答案:

答案 0 :(得分:2)

未经测试,因为您未提供任何样本输入和预期输出:

awk '
NR==FNR { keys = keys sep $0; sep = "|"; next }
{ gsub("class=\"(" keys ")\"","style=\"xxxx\"") }
1' keys file_to_process > tmp$$ &&
mv tmp$$ file_to_process

答案 1 :(得分:1)

我认为现在是Perl(未经测试)的时候了:

my $keyfilename = 'somekeyfile'; // or pick up from script arguments
open KEYFILE, '<', $keyfilename or die("Could not open key file $keyfilename\n");
my %keys = map { $_ => 1 } <KEYFILE>; // construct a map for lookup speed
close KEYFILE;

my $htmlfilename = 'somehtmlfile'; // or pick up from script arguments
open HTMLFILE, '<', $htmlfilename or die("Could not open html file $htmlfilename\n");
my $newchunk = qq/class="xxxx"/;
for  my $line (<$htmlfile>) {
    my $newline = $line;
    while($line =~ m/(class="([^"]+)")/) {
        if(defined($keys{$2}) {
            $newline =~ s/$1/$newchunk/g;
        }
    }
    print $newline;
}

这使用哈希来查找键,这应该相当快,并且当行包含类语句时,仅在键本身上执行此操作。

答案 2 :(得分:0)

尝试使用密钥文件中的所有子命令生成一个非常长的sed脚本,如:

s/class=\"key1\"/style=\"xxxx\"/g; s/class=\"key2\"/style=\"xxxx\"/g ...

并使用此文件。 这样您只需读取输入文件一次。

答案 3 :(得分:0)

这是使用GNU awk的一种方式:

awk 'FNR==NR { array[$0]++; next } { for (i in array) { a = "class=\"" i "\""; gsub(a, "style=\"xxxx\"") } }1' keys.txt file.txt

请注意,keys.txt中的键被视为整行,包括空格。如果领先和滞后的空白可能成为问题,请使用$1代替$0。不幸的是,如果没有一些样本数据,我无法正确测试。 HTH。

答案 4 :(得分:0)

首先将您的密钥文件转换为sed或模式,如下所示:key1|key2|key3|...。这可以使用tr命令完成。拥有此模式后,您可以在单个sed命令中使用它。

尝试以下方法:

sed -i -r  "s/class=\"($(tr '\n' '|' < keys | sed 's/|$//'))\"/style=\"xxxx\"/g" file