需求概要描述
- 数据是csv格式转成的,间隔为英文逗号,每列数据有双引号包含。且备注数据列中本身自带有英文逗号;例如“文档,调用”
- 系统应用为C编写的一个解密程序,即一个可执行文件
- 现在需要读取每一行数据,获取最后一列数据,用解密程序解密后,在这一行后面新增一列,并附加上解密后的内容
- 注意保持csv原始格式,即引号逗号的格式,例如:"orderno","phone_no","加密数据","解密后数据"
实现
要选取好awk的分隔符,可以选用英文逗号做分隔符,但是要小心备注字段中的英文逗号引起列分隔异常。如果要选用逗号做分隔符可以直接用$NF来取得最后一列。也可以用组合分隔符,比如-F"["][,]["]"即","为分隔符。
此处为了方便直接用的逗号做分隔符
- 方法一:使用while read循环读取每行,逐行处理。速度120条/s左右
while read line; do res=`echo ${line} |awk -F[,] '{print $NF}'|awk -F[\"] '{print $2}'`; res1=`/data/dp_dir/decode/a.out ${res}`; echo ${line}",\""${res1}"\"">>./f1.txt; done < /data/dp_dir/decode/f.txt
- 方法二:使用awk直接读取文件,并用system调用组合成的命令。速度120条/s左右
awk -F[,] 'BEGIN{while(getline < "/data/dp_dir/decode/f2.txt"){a=substr($NF,2,length($NF)-2);b="'\''"$0"'\'',\\\"";cmd="echo "b"`/data/dp_dir/decode/a.out "a"`\\\"";system(cmd)};close("/data/dp_dir/decode/f2.txt");}'>> f6.txt
- 方法三:使用awk直接读取文件,将组合成的命令输出到文本,并用sh调用这个文本。速度300条/s左右
awk -F[,] 'BEGIN{while(getline < "/data/dp_dir/decode/f2.txt"){a=substr($NF,2,length($NF)-2);b="'\''"$0"'\'',\\\"";cmd="echo "b"`/data/dp_dir/decode/a.out "a"`\\\"";print cmd};close("/data/dp_dir/decode/f2.txt");}'>> f6.txt;sh f6.txt >> f7.txt
用strace -c -p跟踪了以下,发现方法一和方法二花费了96%的cpu时间在wait4调用上,所以慢了很多。
- 方法四 使用gnu parallel在方法三的基础上加并行,方法三需要半个小时才能完成,并行只需要30-40秒
wget http://ftp.gnu.org/gnu/parallel/parallel-20190422.tar.bz2
tar -jxvf parallel-20190422.tar.bz2
cd parallel-20190422.tar.bz2
./configure --prefix=/usr/local/gnu
make && sudo make install
awk -F[,] 'BEGIN{while(getline < "/data/dp_dir/decode/f2.txt"){a=substr($NF,2,length($NF)-2);b="'\''"$0"'\'',\\\"";cmd="echo "b"`/data/dp_dir/decode/a.out "a"`\\\"";print cmd};close("/data/dp_dir/decode/f2.txt");}'>> f6.txt;cat f6.txt | /usr/local/gnu/bin/parallel --pipe sh >> ./f9.txt
- 方法五 因为在system调用中不能得到调用的结果,只能获取到执行状态结果,0,1或者其他什么的,所以就不逐行处理了,直接批量生产echo语句放入文本中,在sh调用这个文本。类似于方法四。
time awk -F[,] '{a=substr($NF,2,length($NF)-2);print "echo '\''"$0"'\'',\\\"`/data/dp_dir/decode/a.out "a"`\\\""}' f2.txt >> f11.txt;time cat f11.txt|/usr/local/gnu/bin/parallel --pipe sh >> ./f13.txt