Bash 从awk调用shell的速度非常慢
我想在运行时处理awk中的值。 值通过二进制进行处理。 我试着按照下面的方法来做,但是速度很慢。不能用的慢。 500万条未经此处理的记录在30秒内完成。有了它,我等了几个小时,没有结果 我做错什么了吗? 是否有正确的方法使用外部应用程序处理awk中的值 bash呼叫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
#!/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