在CSV文件中应用RIPEMD的另一种方法

时间:2017-04-06 11:08:06

标签: bash shell awk hash ripemd

我正在寻找另一种方法将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。

您能否帮助我提供另一种想法和方法来更快地获取数据。

提前致谢

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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中测试)。
  • 批处理级别的fork将比来自awk的fork更快,包括管道fork,捕获回复
  • 不是openssl ripemd160的专家,但是可能有另一种方法来处理批量处理中的元素,而不是每次都从同一个文件/源打开一个分支

答案 2 :(得分:0)

你的解决方案击中Cygwin最受伤的地方:产生新程序。 Cygwin在这方面很慢。

您可以通过使用计算机中的所有核心来加快速度,但速度仍然很慢。

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

riper.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核上,它处理1 GB文件,在300秒内处理139482000行。

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