从awk调用shell非常慢

问题描述 投票:1回答:1

我想在运行中处理awk中的值。值通过二进制处理。我正在尝试按照以下方式执行此操作,但这是非常缓慢的。无法缓慢。没有这个处理的500万条记录在30秒内完成。有了它 - 我等了几个小时没有最终结果。

难道我做错了什么?有没有一种正确的方法来使用外部应用程序处理awk中的值?

打电话

#!/bin/bash
...    
cat ${INFILE} | awk -F"\t" -v sh_dir="${DIRECTORY_PATH_SH}" outfile="${OUTFILE}" -f process.awk

process.awk

{   
    cmd=sh_dir"/sha_cipher"
    print $2 |& cmd
    close(cmd, "to")
    cmd |& getline encrypted_id
    close(cmd)

    printf "%s\t%s\t%s\n", $1, encrypted_id, $19 >> outfile
}

INPUT:

2018-09-14 | AlexOrange | 15 | HTTP | 86914702 | 1 | 1 |没有| 79634 | 48249 | 127883 |左| MODEL1 | SUBTYPE255 A536 | RS | SO | 94 | Elixir | RTT

OUTPUT:

2018-09-14 | 36c8387b7e334c38786d6d497b | RTT

bash awk
1个回答
2
投票

我的PC上没有sha_cipher,但让我们想象你的shell命令是tr 'a-z' 'A-Z'而不是sha_cipher。查看(制表符分隔输入):

$ cat file
2018-09-14      AlexOrange      15      HTTP    86914702        1       1       NO      79634   48249   127883  LEFT    MODEL1  SUBTYPE255 A536 RS      SO      94     Elixir   RTT
2018-09-14      Joe Bloggs      15      HTTP    86914702        1       1       NO      79634   48249   127883  LEFT    MODEL1  SUBTYPE255 A536 RS      SO      94     Elixir   RTT
2018-09-14      Sue Everyone    15      HTTP    86914702        1       1       NO      79634   48249   127883  LEFT    MODEL1  SUBTYPE255 A536 RS      SO      94     Elixir   RTT

$ cut -f2 file | tr 'a-z' 'A-Z'
ALEXORANGE
JOE BLOGGS
SUE EVERYONE

$ cut -f2 file | tr 'a-z' 'A-Z' |
awk 'BEGIN{FS=OFS="\t"} NR==FNR{a[NR]=$0;next} {print $1, a[FNR], $19}' - file
2018-09-14      ALEXORANGE      RTT
2018-09-14      JOE BLOGGS      RTT
2018-09-14      SUE EVERYONE    RTT

假设sha_cipher可以对像tr这样的管道输入中的多个值进行操作,并且大多数其他文本处理shell命令可以(切割),那将比使用awk启动子shell为每个输入行调用一次shell命令效率高几个数量级。 ,sed,grep,sort,uniq等...)。

为了测试时间,我使用与您提供的样本输入行相同的格式创建了一个包含500万行的文件,并使用以下内容在第二个字段中包含随机字符串:

$ cat file
2018-09-14      AlexOrange      15      HTTP    86914702        1       1       NO      79634   48249   127883  LEFT    MODEL1  SUBTYPE255 A536 RS      SO      94     Elixir   RTT

$ tr -dc '[:alnum:]' </dev/urandom | fold -w 6 | head -5000000 |
awk 'BEGIN{FS=OFS="\t"} NR==FNR{orig=$0;next} {x=$0; $0=orig; $2=x}1' file - > file5m

$ wc -l file5m
5000000 file5m

$ head -3 file5m
2018-09-14      fLSynM  15      HTTP    86914702        1       1       NO      79634   48249   127883  LEFT    MODEL1  SUBTYPE255 A536 RS      SO      94      Elixir RTT
2018-09-14      mxWzLF  15      HTTP    86914702        1       1       NO      79634   48249   127883  LEFT    MODEL1  SUBTYPE255 A536 RS      SO      94      Elixir RTT
2018-09-14      EKJYF8  15      HTTP    86914702        1       1       NO      79634   48249   127883  LEFT    MODEL1  SUBTYPE255 A536 RS      SO      94      Elixir RTT

这是运行建议的解决方案的结果:

$ time cut -f2 file5m | tr 'a-z' 'A-Z' | awk 'BEGIN{FS=OFS="\t"} NR==FNR{a[NR]=$0;next} {print $1, a[FNR], $19}' - file5m > outFile5m
real    0m40.892s
user    0m42.196s
sys     0m0.980s

$ wc -l outFile5m
5000000 outFile5m

$ head -3 outFile5m
2018-09-14      FLSYNM  RTT
2018-09-14      MXWZLF  RTT
2018-09-14      EKJYF8  RTT

因此,除非sha_cipher的效率远远低于tr 'a-z' 'A-Z'(如果那时你只是运气不好),那么我预计上述应该足够快地运行(即它应该在一分钟内运行而不是花几个小时)。

© www.soinside.com 2019 - 2024. All rights reserved.