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

Bash 在CSV文件中应用RIPEMD的另一种方法,bash,shell,awk,hash,ripemd,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)

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

你能帮我找到另一种更快获取数据的方法吗

提前谢谢

# 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
注:

  • 未测试(因此打印可能需要使用escape进行一些调整)
  • 无错误处理(假设一切正常)。我建议做一些测试(比如在回复中包含行参考,在第二个awk中进行测试)
  • 批处理级别的fork将比来自awk的fork(包括管道fork)快得多,从而获得回复
  • 不是openssl ripemd160的专家,但可能有另一种方法来处理批量进程中的元素,而不必每次打开来自同一文件/源的fork

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


你的解决方案对Cygwin的影响最大:产生新的程序。Cygwin在这方面非常慢

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

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

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并行可以有所帮助。如果您的软件包系统中没有GNU Parallel 20161222或更高版本,则可以将其安装为:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
您需要安装Perl才能运行GNU并行:

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)。

对不起,它不起作用,我得到的每一行求值都是C:/hanatest/MD160。求值:第1行:(stdin)=:未找到命令在
$(…)>
之前缺少第一个回音,请重新编写,我真的不知道我应该在哪里写回音,提前感谢代码已经被改编,所以只需复制/粘贴当前版本。我在这里测试
time
在小文件上增加33%,在大文件上增加近50%。对于初学者,你应该用
time
对当前代码进行基准测试(例如
time awk-F.)-v..
)以及使用openssl speed ripemd160时CPU的理论极限。它将帮助你知道你离你能达到的目标还有多远。如果您接近最大速度,则无法进行太多优化。时间的损失不在于openssl,而在于awk内部和使用有限的资源(无并行,一次1个fork)中的forking和IO to shell。优化通常会返回比线性减少好得多的时间(即使它已经肯定是一个很好的增益)。从CSV文件中获得几行代码和您想要的预期输出会很有帮助。我正在与Cygwin合作,我没有找到并行。我可以在cygwin中安装并使用它吗?检查此链接-并非所有版本的并行程序都支持
--管道
选项。请确保安装一个支持它的并行程序。@Houssem-让我们向parallel cmd developer寻求帮助。@OleTange-您能提供有价值的建议来解决这个问题吗。
key=a
export key
parallel --pipe-part --block -1 -a source.csv -k python riper.py > ziel.csv