我有一个文件“items.txt”,其中包含我需要从文件“text.txt”中删除的100,000个项目的列表,并替换为“111111111”。
我写了这个脚本,它完全符合我的意图:
#!/bin/bash
a=0
b=`wc -l < ./items.txt`
while read -r line
do
a=`expr $a + 1`
sed -i "s/$line/111111111/g" text.txt
echo "Removed ("$a"/"$b")."
done < ./items.txt
此脚本查看“items.txt”中的eat行,然后使用sed
从“text.txt”中删除每一行。
但这个脚本非常慢。据我估计,从我的计算机上删除文件中的所有项目需要1周以上的时间。有没有更快捷的方法来快速更换所有项目?
BASH 4.1.5
答案 0 :(得分:2)
使用sed构建一个sed脚本来替换所有项目:
sed 's/^/s=/;s/$/=111111111=g/' items.txt | sed -f- text.txt
更新:以下Perl脚本似乎更快:
#!/usr/bin/perl
use warnings;
use strict;
open my $ITEMS, '<', 'items.txt';
my @items = <$ITEMS>;
chomp @items;
my $regex = join '|', @items;
$regex = qr/$regex/;
open my $TEXT, '<', 'text.txt';
while (<$TEXT>) {
s/$regex/111111111/g;
print;
}
答案 1 :(得分:1)
输出会减慢您的脚本速度。删除它,你会发现一个显着的加速。 要删除的行:
echo "Removed ("$a"/"$b")."
答案 2 :(得分:1)
你的脚本很慢,不仅仅是因为输出(echo "Removed ("$a"/"$b")."
)。
主要原因是,您有
sed -i "s/$line/111111111/g" text.txt
在while循环中。例如,您的items.txt
有10k行,sed行将执行10k次。也就是说,阅读text.txt
到10k次。如果text.txt也是10k,则为10k * 10k
你可以做得更好的是,只读一次这两个文件:
awk 'NR==FNR{a[$0];next}$0 in a{$0="1111111"}1' items.txt text.txt
我没有测试,但它应该可以工作。