循环访问文件中的记录并替换另一个文件上的内容的最快方法

Fastest way to iterates through records in file and replace contents on another file

提问人:Slug 提问时间:12/15/2022 最后编辑:brian d foySlug 更新时间:12/16/2022 访问量:71

问:

需要有关从包含值列表(~30k 行)的文件读取并使用这些值在 Linux 中搜索和替换另一个文件(~500k 行)中的内容的最快方法的建议。

目前,我正在遍历列表文件并形成“sed -e”命令,然后执行该命令。但是,需要 ~1 小时才能完成。

我希望将花费的时间减少 50%。

以下是我当前使用的代码片段:

declare -a sedArgs

while IFS="" read -r line; do
    IFS=',' read -ra cols <<< ${line}

    col2=$(echo "${col2}" | sed 's/\*/\\*/g' | sed 's/\./\\./g')
    col4=$(echo "${col4}" | sed 's/\*/\\*/g' | sed 's/\./\\./g')

    sedArgs+=("-e")
    sedArgs+=("s|${col2}${col1}|${col4}${col3}|g")
fi
done < list.txt

sed -i "${sedArgs[@]}" target.txt

列表.txt示例:

OLDVAL1,1234,NEWVAL1,1222
OLDVAL2,2234,NEWVAL2,2222

target.txt 示例:

CUST1             OLDVAL1             1234 00000000000000000
CUST2             OLDVAL2             2234 00000000000000000
与语言无关

评论

2赞 Nic3500 12/15/2022
根本不使用 bash。Perl 更快,python 更快,编译语言(即 C)更好。Shell 对于快速和肮脏是可以的,但如果你想要性能,你必须使用不会在每次做某事时都启动新 shell 的语言。
1赞 zdim 12/15/2022
请:发布问题的准确说明(“搜索和替换”......how?)、您的代码以及每个文件的几行。(原则上,构建第一个文件的哈希/字典,并将其用于搜索第二个文件......但我无法判断这是否适用于您的问题,这没有描述)
0赞 pynexj 12/15/2022
定义“最快”。
0赞 Jetchisel 12/15/2022
在处理文本文件时嵌入 shell 循环确实会使其非常非常非常慢,但是是的,您在循环中有 4 次调用,所以这慢了 4 倍......sedsed
0赞 Jetchisel 12/15/2022
unix.stackexchange.com/questions/169716/......

答:

2赞 zdim 12/15/2022 #1

使用第一个文件中的新旧对构建哈希值,并将其用于替换

use warnings;
use strict;
use feature 'say';

use Path::Tiny;  # for convenience to read a file

my $repl_data_file = 'list.txt';

my %repl = map { (split /,/)[0,2] } path($repl_data_file)->lines;

while (<>) { 
    s{\S+ \s+\K (\S+) (.*)}{ ($repl{$1}//$1) . $2 }ex;
    print
}

运算符在命令行上读取名称为的逐行文件,因此请使用此文件(将输出重定向到文件)。<>prog.pl target.txt > new_target.txt

由于描述很少,我做了一些假设:文件在第一列和第三列中具有新旧值,目标文件中要替换的值在第二列中。list.txt

对于所描述的文件(大小为 30k 与 500k 行),这应该只需要几秒钟。


为了方便起见,我使用 Path::Tiny。这是一个非常有用的模块,易于安装,但这里是仅使用内置工具的替代方案

my %repl =
    map { (split /,/)[0,2] }
    do { open my $fh, $repl_data_file or die $!; <$fh> };

评论

0赞 zdim 12/15/2022
我没有解释,以免内容混乱——让我知道需要澄清什么。