美文网首页文本处理(grep, sed和awk等)Awk
awk处理文档:调用系统应用处理最后一列数据

awk处理文档:调用系统应用处理最后一列数据

作者: 读或写 | 来源:发表于2019-05-15 11:08 被阅读1次

    需求概要描述

    • 数据是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
    

    相关文章

      网友评论

        本文标题:awk处理文档:调用系统应用处理最后一列数据

        本文链接:https://www.haomeiwen.com/subject/kvpuaqtx.html