Bash 从awk调用shell的速度非常慢

Bash 从awk调用shell的速度非常慢,bash,awk,Bash,Awk,我想在运行时处理awk中的值。 值通过二进制进行处理。 我试着按照下面的方法来做,但是速度很慢。不能用的慢。 500万条未经此处理的记录在30秒内完成。有了它,我等了几个小时,没有结果 我做错什么了吗? 是否有正确的方法使用外部应用程序处理awk中的值 bash呼叫 #!/bin/bash ... cat ${INFILE} | awk -F"\t" -v sh_dir="${DIRECTORY_PATH_SH}" outfile="${OUTFILE}" -f process.awk

我想在运行时处理awk中的值。 值通过二进制进行处理。 我试着按照下面的方法来做,但是速度很慢。不能用的慢。 500万条未经此处理的记录在30秒内完成。有了它,我等了几个小时,没有结果

我做错什么了吗? 是否有正确的方法使用外部应用程序处理awk中的值

bash呼叫

#!/bin/bash
...    
cat ${INFILE} | awk -F"\t" -v sh_dir="${DIRECTORY_PATH_SH}" outfile="${OUTFILE}" -f process.awk
过程。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
}
输入:

2018-09-14 | Alexange | 15 | HTTP | 86914702 | 1 | 1 | NO | 79634| 48249 | 127883 |左|模型1 |亚型255 A536 | RS | SO | 94| 长生不老药

输出:

2018-09-14 | 36c8387b7e334c38786d6d497b | RTT


我的电脑上没有
sha_密码
,但让我们想象一下,您的shell命令是
tr'a-z''a-z'
,而不是
sha_密码
。外观(制表符分隔输入):

假设
sha_cipher
可以对管道输入中的多个值进行操作,例如
tr
和大多数其他文本处理shell命令(cut、sed、grep、sort、uniq等),那么这将比让awk启动子shell为每行输入调用shell命令要高效好几个数量级

为了测试计时,我创建了一个文件,其中包含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

因此,除非
sha_cipher
的效率远远低于
tr'a-z'a-z'
(如果是的话,那么你只是运气不好),否则我希望上述操作对你来说应该足够快(即,它应该在一分钟内运行,而不是花几个小时).

请将示例输入和该示例输入所需的输出添加到您的问题中。您每次都在调用一个新流程,500万条记录即500万个子流程。这些不是同时运行的,但它不会重用它们。我所能建议的最好方法是使用一种内置
sha_cipher
功能的语言,比如python。顺便说一句,
cat
是另一个不必要的子进程(并不是说当你有5000000个时它会有很大的不同)。@Cyrus添加了示例输入和输出。为了清晰起见,我将制表符分隔符改为“|”。@cdarke我们在不同的城市有十几个已建立的环境。从管理层批准到部署,添加新技术存在一些困难。此外,我们已经使用了许多技术。我们真的不想增加技术储备——这会带来一些不良后果。好极了!我是如此的过度复杂的解决方案。非常感谢你!对密码是使用标准输入法的“C”二进制文件。我可以通过管道输入数据。谢谢你的解释。
$ 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