search类似的问题,找不到任何适合我的需求:
我有一个非常大的HTML文件从多个网站刮,我想全部取代
class="key->from 2nd file"
同
style="xxxx"
目前我使用sed
– 它运作良好,但只有小文件
同时阅读密钥; do 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
未经测试,因为您没有提供任何示例输入和预期输出:
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
我认为是时候到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; }
这使用一个散列来查找关键字,这应该是相当快的,并且只有在关键字本身包含一个类语句时才会执行。
尝试使用keys文件中的所有子命令生成一个非常长的sed脚本,如下所示:
s/class=\"key1\"/style=\"xxxx\"/g; s/class=\"key2\"/style=\"xxxx\"/g ...
并使用这个文件。 这样您将只读取一次输入文件。
这里有一个使用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。
首先将你的密钥文件转换成如下所示的sed或pattern: key1|key2|key3|...
这可以使用tr
命令完成。 一旦你有了这个模式,你可以在一个sed命令中使用它。
尝试以下操作:
sed -i -r "s/class=\"($(tr '\n' '|' < keys | sed 's/|$//'))\"/style=\"xxxx\"/g" file