0

我有一个文件“items.txt”,其中包含我需要从文件“text.txt”中删除并替换为“111111111”的 100,000 个项目的列表。

我编写了这个脚本,它完全按照我的意图工作:

#!/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”中的吃线,然后用于sed从“text.txt”中删除每一行。

这个脚本虽然很慢。据我估计,从我计算机上的文件中删除所有项目需要 1 周多的时间。有没有更有效的方法来快速更换所有物品?

重击 4.1.5

4

3 回答 3

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;
}
于 2013-04-19T23:35:35.527 回答
1

输出会减慢您的脚本。删除它,您会注意到显着的加速。要删除的行:

 echo "Removed ("$a"/"$b")."
于 2013-04-19T23:28:23.923 回答
1

您的脚本很慢,不仅是因为输出 ( echo "Removed ("$a"/"$b").")。

主要原因是,你有

 sed -i "s/$line/111111111/g" text.txt

在一个while循环中。例如,您items.txt有 10k 行,sed 行将执行 10k 次。也就是说,通读text.txt10k 次。如果你的 text.txt 也是 10k,那就是10k * 10k

你可以做得更好的是,两个文件只读取一次:

awk 'NR==FNR{a[$0];next}$0 in a{$0="1111111"}1' items.txt text.txt

我没有测试,但它应该工作。

于 2013-04-19T23:36:32.450 回答