1

我正在寻找另一种将 RIPEMD-160 应用于 csv 文件的第二列的方法。

这是我的代码

awk -F "," -v env_var="$key" '{
    tmp="echo -n \047" $2 env_var "\047 | openssl ripemd160 | cut -f2 -d\047 \047"
    if ( (tmp | getline cksum) > 0 ) {
        $3 = toupper(cksum)
    }
    close(tmp)
    print
}' /test/source.csv > /ziel.csv

我在一个大的 csv 文件(1Go)中运行它,它需要 2 天,我只得到 100Mo,这意味着我需要等待一个月才能得到我所有的新 CSV。

你能帮我用另一种想法和方法来更快地获取我的数据吗?

提前致谢

4

3 回答 3

1

您可以使用 GNU Parallel 通过并行执行 awk 命令来提高输出速度对于解释检查here

cat /test/source.csv | parallel --pipe awk -F "," -v env_var="$key" '{
    tmp="echo -n \047" $2 env_var "\047 | openssl ripemd160 | cut -f2 -d\047 \047"
    if ( (tmp | getline cksum) > 0 ) {
        $3 = toupper(cksum)
    }
    close(tmp)
    print
}' > /ziel.csv
于 2017-04-06T12:01:49.630 回答
0
# prepare a batch (to avoir fork from awk)
awk -F "," -v env_var="$key" '
    BEGIN {
       print "if [ -r /tmp/MD160.Result ];then rm /tmp/MD160.Result;fi"
       }
    {
    print "echo \"\$( echo -n \047" $2 env_var "\047 | openssl ripemd160 )\" >> /tmp/MD160.Result"
    } ' /test/source.csv > /tmp/MD160.eval

# eval the MD for each line with batch fork (should be faster)
. /tmp/MD160.eval

# take result and adapt for output
awk '
   # load MD160
   FNR == NR { m[NR] = toupper($2); next }
   # set FS to ","
   FNR == 1 { FS = ","; $0 = $0 "" }
   # adapt original line
   { $3 = m[FNR]; print}
   ' /tmp/MD160.Result /test/source.csv   > /ziel.csv

笔记:

  • 未经测试(因此打印可能需要一些调整与转义)
  • 没有错误处理(假设一切正常)。我建议进行一些测试(例如在回复中包含行参考并在第二个 awk 中进行测试)。
  • 批处理级别的分叉将比来自 awk 的分叉(包括管道分叉)快得多,捕获回复
  • 不是openssl成熟md160的专家,但可能有另一种方法来处理批量过程中的元素,而无需每次都打开来自同一文件/源的fork
于 2017-04-06T11:39:11.337 回答
0

您的解决方案对 Cygwin 造成了最大的伤害:生成新程序。Cygwin 在这方面非常缓慢。

您可以通过使用计算机中的所有内核来加快速度,但它仍然会非常慢。

您需要一个不启动其他程序的程序来计算 RIPEMD 和。这是一个小的 Python 脚本,它在标准输入上获取 CSV,并在标准输出上输出 CSV,第二列替换为 RIPEMD 总和。

成熟的.py:

#!/usr/bin/python                                                                                  

import hashlib
import fileinput
import os

key = os.environ['key']

for line in fileinput.input():
    # Naiive CSV reader - split on ,                                                               
    col = line.rstrip().split(",")
    # Compute RIPEMD on column 2                                                                   
    h = hashlib.new('ripemd160')
    h.update(col[1]+key)
    # Update column 2 with the hexdigext                                                           
    col[1] = h.hexdigest().upper();
    print ','.join(col)

现在你可以运行:

cat source.csv | key=a python riper.py > ziel.csv

这仍然只会使用系统的一个核心。使用所有核心 GNU Parallel 可以提供帮助。如果您的软件包系统中没有 GNU Parallel 20161222 或更新版本,它可以安装为:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

您需要安装 Perl 才能运行 GNU Parallel:

key=a
export key
parallel --pipe-part --block -1 -a source.csv -k python riper.py > ziel.csv

这将即时将 source.csv 切成每个 CPU 核心的一个块,并为每个块运行 python 脚本。在我的 8 核上,这会在 300 秒内处理一个 1 GB 的文件,其中包含 139482000 行。

如果您需要它更快,您将需要转换riper.py为编译语言(例如 C)。

于 2017-04-09T10:21:02.920 回答