作为一个 perl 程序员,我认为使用 --tagstring 会相当容易,但基本上我想从 Parallel 中单独为每个作业的每一行输出添加时间戳。就像,用正确的“STUFF”替换,输出可能看起来像,假设毫秒分辨率(尽管纳秒分辨率也很好):
$ seq 8 | parallel --tags 'sequence {} {=STUFF=}' -j2 'sleep=$((1 + RANDOM % 2)); echo sleeping $sleep; sleep $sleep; echo done; echo $sleep {#} {%} {}'
sequence 1 0.001 sleeping 1
sequence 1 1.001 done
sequence 1 1.002 1 1 1 1
sequence 2 0.001 sleeping 2
sequence 2 2.001 done
sequence 2 2.002 2 2 2 2
sequence 3 0.001 sleeping 2
sequence 3 2.001 done
sequence 3 2.002 2 3 1 3
sequence 5 0.001 sleeping 1
sequence 5 1.001 done
sequence 5 1.002 1 5 1 5
sequence 4 0.001 sleeping 2
sequence 4 2.001 done
sequence 4 2.002 2 4 2 4
sequence 6 0.001 sleeping 1
sequence 6 1.001 done
sequence 6 1.002 1 6 1 6
sequence 7 0.001 sleeping 2
sequence 7 2.001 done
sequence 7 2.002 2 7 2 7
sequence 8 0.001 sleeping 2
sequence 8 2.001 done
sequence 8 2.002 2 8 1 8
答案1
你可能会误认为这很容易,我不能因此责怪你。
但是,无法正常输出。
这是因为标记字符串仅计算两次,并且仅添加后工作已完成。
GNU 并行运行:
job1 > tmpout1 2> tmperr1
job2 > tmpout2 2> tmperr2
job3 > tmpout3 2> tmperr3
(这当然不是100%正确,但已经足够接近了)。
当作业完成时,GNU Parallel 会tmp*
以大块的形式读取文件,在前面添加--tagstring
并输出作业。
这里重要的部分是:标记是不是跑步时完成。并且--tagstring
仅计算两次:作业开始之前和作业完成之后(这是将被添加的最终结果)。
选择这种设计是因为计算标记字符串会消耗 CPU,如果您的输出是 3600000 行,那么即使 1 毫秒/行的延迟也会导致 1 小时(!)的等待。
然而,有一个例外:--line-buffer
。
--line-buffer
做计算每行输出的标签字符串。之所以选择这种设计,是因为它--line-buffer
已经占用了更多的 CPU 时间(必须从每个正在运行的作业中轮询新数据,并且无法仅处理大数据块)。
所以这有效:
$ seq 8 | parallel --lb --tagstring 'sequence {} {= $start{$job}||=::now(); $_=sprintf"%06.3f",::now()-$start{$job} =}' -j2 'sleep 1; echo Begin {}; sleep 0.{}; echo End {}'|sort
sequence 1 01.027 Begin 1
sequence 1 01.116 End 1
sequence 2 01.024 Begin 2
sequence 2 01.216 End 2
sequence 3 01.098 Begin 3
sequence 3 01.312 End 3
sequence 4 01.049 Begin 4
sequence 4 01.411 End 4
sequence 5 01.031 Begin 5
sequence 5 01.509 End 5
sequence 6 01.039 Begin 6
sequence 6 01.613 End 6
sequence 7 01.048 Begin 7
sequence 7 01.711 End 7
sequence 8 01.071 Begin 8
sequence 8 01.811 End 8