2

搜索了类似的问题,但找不到完全符合我需求的东西:

我有一个从多个网站抓取的非常大的 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

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

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

5 回答 5

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
于 2012-10-30T15:11:10.800 回答
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;
}

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

于 2012-10-30T15:25:43.003 回答
0

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

尝试以下操作:

sed -i -r  "s/class=\"($(tr '\n' '|' < keys | sed 's/|$//'))\"/style=\"xxxx\"/g" file
于 2012-10-30T15:11:13.457 回答
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。

于 2012-10-30T15:05:48.187 回答
0

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

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

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

于 2012-10-30T15:05:45.697 回答