从并行生成的三个其他流中创建单个输出流

Cer*_*era 10 pipe text-processing split parallelism

我有三种不同格式的数据;对于每种数据类型,都有一个 Python 脚本将其转换为单一的统一格式。

这个 Python 脚本很慢并且受 CPU 限制(到多核机器上的单核),所以我想运行它的三个实例 - 每个数据类型一个 - 并将它们的输出组合起来将它传递到sort. 基本上,相当于:

{ ./handle_1.py; ./handle_2.py; ./handle_3.py } | sort -n
Run Code Online (Sandbox Code Playgroud)

但是三个脚本并行运行。

我发现了这个问题,其中 GNUsplit被用来在处理流的脚本的 n 个实例之间循环一些标准输出流。

从拆分手册页:

-n, --number=CHUNKS
          generate CHUNKS output files.  See below
CHUNKS  may be:
 N       split into N files based on size of input
 K/N     output Kth of N to stdout
 l/N     split into N files without splitting lines
 l/K/N   output Kth of N to stdout without splitting lines
 r/N     like 'l'  but  use  round  robin  distributio
Run Code Online (Sandbox Code Playgroud)

所以这个r/N命令意味着“没有分割线”。

基于此,似乎以下解决方案应该是可行的:

split -n r/3 -u --filter="./choose_script" << EOF
> 1
> 2
> 3
> EOF
Run Code Online (Sandbox Code Playgroud)

这是在哪里choose_script做的:

#!/bin/bash
{ read x; ./handle_$x.py; }
Run Code Online (Sandbox Code Playgroud)

不幸的是,我看到一些行的混合 - 以及许多不应该存在的换行符。

例如,如果我用一些执行此操作的简单 bash 脚本替换我的 Python 脚本:

#!/bin/bash
# ./handle_1.sh
while true; echo "1-$RANDOM"; done;
Run Code Online (Sandbox Code Playgroud)

.

#!/bin/bash
# ./handle_2.sh
while true; echo "2-$RANDOM"; done;
Run Code Online (Sandbox Code Playgroud)

.

#!/bin/bash
# ./handle_3.sh
while true; echo "3-$RANDOM"; done;
Run Code Online (Sandbox Code Playgroud)

我看到这个输出:

1-8394

2-11238
2-22757
1-723
2-6669
3-3690
2-892
2-312511-24152
2-9317
3-5981
Run Code Online (Sandbox Code Playgroud)

这很烦人 - 基于我上面粘贴的手册页摘录,它应该保持行的完整性。

显然,如果我删除-u参数,它会起作用,但是它会被缓冲并且我会耗尽内存,因为它会缓冲除一个脚本之外的所有脚本的输出。

如果有人在这里有一些见解,将不胜感激。我在这里超出了我的深度。

flo*_*lok 2

尝试使用 GNU 并行的 -u 选项。

echo "1\n2\n3" | parallel -u -IX ./handle_X.sh
Run Code Online (Sandbox Code Playgroud)

这会并行运行它们,而不缓冲整个进程。