gpt4 book ai didi

shell - 是否有类似 xargs 的管道数据而不是使用参数?

转载 作者:行者123 更新时间:2023-12-01 13:12:41 26 4
gpt4 key购买 nike

xargs 如果您有一个通过命令行参数接受其输入的命令,那么它很棒,但如果您有一个通过标准输入接受其输入的命令,它就没有那么有用了。

我所看到的针对类似这种情况的建议是使用 tee 将行复制到多个下游进程,如下所示:

producer | tee >(consumer0 >out0) >(consumer1 >out1) >(consumer2 >out2) | consumer3 >out3;
cat out* | next-stage-of-pipeline

这有一个缺点,即所有消费者都收到所有生产的行,并且假设 consumer{0..3} 是不同的进程。如果我需要每个消费者都相同,并处理部分输入(例如,并行化一个顺序消费者),它也不会工作。

我正在寻找的是像 xargs 这样的东西,它允许在同一消费者的多个实例之间拆分工作,然后组合输入并继续处理。输出组合的方式应该模仿 xargs,所以不能保证行的顺序,但两行不会拼接在一起(例如:“Hello Fred”和“Hello George”可能会出现以任何顺序,但您不会看到“HHello GeoFregedello”)。

这样的事情的主要用途是处理大量数据,如果为每一行输入启动一个消费者,那么消费者的启动延迟会很明显。如果 consumer 的启动成本很低,我会简单地将它包装在一个小的 shell 脚本中,该脚本将它的参数通过管道传递给 consumer 并使用 xargs 调用它.

至少对于我想到的用例,生产者将从内部服务中获取大量数据,之后消费者需要转换该数据并进行一些 API 调用。所以生产者和消费者都将是长时间运行的进程,并行运行 API 调用确实会加快速度。

像这样的东西是理想的,但我一直无法找到这样做的东西:

producer | ??? -P20 consumer | next-stage-of-pipeline

是否有提供此功能的命令行工具?

最佳答案

我认为 GNU Paralell 可能会满足您的需求。

producer | parallel consumer | next command in pipeline

编辑:在我开始玩 parallel 之前,我完全理解这个问题。 Parallel 可以将函数作为消费者,您可以在该函数内使用流。

例如

consumer () 
{
echo "$@" | awk '{print $2}'
}
export -f consumer
for i in {1..30}; do echo "foo $i bar"; done | parallel consumer

编辑 2:

您可以使用 --pipe 选项,它将数据通过管道传递给消费者。 -q 参数将 shell 引号放在消费者周围:

for i in {1..30}; do echo "foo $i bar"; done | parallel --pipe -q awk '{print $2}'

奖金:

  1. parallel 将在顺序处理器上运行作业。如果你有 8 个核心和 16 个消费者,每个核心将有 2 个消费者(这是可配置的)
  2. parallel 可以在网络上的多台机器上运行,只要它可以 ssh 到它们而不被提示输入密码(例如使用 ssh-agent ).

关于shell - 是否有类似 xargs 的管道数据而不是使用参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59094551/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com