Bash 在CSV文件中应用RIPEMD的另一种方法
我正在寻找另一种方法,将RIPEMD-160应用于csv文件的第二列 这是我的密码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)
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
你的解决方案对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