9

给定 STDIN 上的以下示例输入:

foo
bar bar
baz
===
qux
bla
===
def
zzz yyy

是否可以在分隔符上拆分它(在这种情况下为“===”)并通过标准输入将其提供给并行运行的命令?

因此,上面的示例输入将导致 3 个并行进程(例如名为 do.sh 的命令),其中每个实例在 STDIN 上接收部分数据,如下所示:

do.sh(实例 1)通过 STDIN 接收到这个:

foo
bar bar
baz

do.sh(实例 2)通过 STDIN 接收到这个:

qux
bla

do.sh(实例 3)通过 STDIN 接收到这个:

def
zzz yyy

我想这样的事情可以使用 xargs 或 GNU 并行,但我不知道如何。

4

3 回答 3

13

GNU Parallel 从版本 20110205 开始可以做到这一点。

cat | parallel --pipe --recend '===\n' --rrs do_stuff
于 2011-01-11T14:26:39.070 回答
3

一般来说,没有。进行此评估的原因之一是从文件而不是终端读取的标准 I/O 一次读取数据块 - BUFSIZ 字节,其中 BUFSIZ 通常是 2 的幂,例如 512 或更大。如果数据在一个文件中,一个进程将读取显示的整个文件 - 如果它们共享相同的打开文件描述,其他进程将什么也看不到(类似于文件描述符,但多个文件描述符可以共享相同的打开文件描述,并且可能在不同的进程中),或者如果它们不共享相同的打开文件描述,则会读取整个相同的文件。

因此,您需要一个进程来读取文件,该进程知道它需要将信息打包到三个进程 - 并且它需要知道如何连接到三个进程。可能是您的分发程序运行三个进程并写入它们各自的管道输入。或者可能是分发器连接到三个套接字并写入不同的套接字。

您的示例没有显示/描述如果有 37 个部分被标记分隔会发生什么。

tpipe我有一个类似于 Unix命令的自制程序tee,但它会将其标准输入的(全部)副本写入每个进程,默认情况下也会写入标准输出。这可能是您需要的合适基础(它至少涵盖了它的流程管理部分)。如果您想要一份副本,请与我联系 - 请参阅我的个人资料。


如果您使用的是 Bash,则可以使用tee带有进程替换的常规来模拟tpipe. 请参阅本文以获取有关方法的说明。

另请参阅SF 96245以获取相同信息的另一个版本 - 加上一个名为的程序的链接,该程序pee非常相似tpipe(相同的基本思想,在各个方面的实现略有不同)。

于 2011-01-11T14:37:05.330 回答
1

您可以使用命名管道来做到这一点。命名管道允许您将标准管道视为文件。您可以拥有多个命名管道并让您的其他程序处理它们。

我对命名管道不是很熟悉,但我经常在这种情况下使用它们。

于 2011-01-11T16:34:20.917 回答