在Bash管道中读取块中的stdin

时间:2016-07-27 07:32:58

标签: linux bash pipe

我有一些shell脚本适用于这样的管道:

foo.sh | bar.sh

我的bar.sh调用一些命令行程序,该程序只能占用一定数量的stdin行。因此,我希望将foo.sh的大型stdout分成N行,以进行多次bar.sh次调用。基本上,分页foo.sh的标准输出并执行多个bar.sh

有可能吗?我希望像foo.sh | ??? | bar.sh之类的管道之间有一些魔力。 xargs -n并没有让我得到我想要的东西。

2 个答案:

答案 0 :(得分:2)

我无法在机器附近进行测试,但您需要GNU Parallel才能轻松实现这一目标:

foo.sh | parallel --pipe -N 10000 -k bar.sh

作为一个额外的好处,它将与你拥有CPU核心并行运行尽可能多的bar.sh

如果您一次只想要一个-j 1,请添加bar.sh

添加--dry-run如果你想知道它会做什么,但不要做任何事情。

答案 1 :(得分:1)

使用while read循环。

foo.sh | while read line1 && read line2 && read line3; do
    printf "%s\n%s\n%s\n" "$line1" "$line2" "$line3" | bar.sh
done

对于大N,写一个循环的函数。

read_n_lines() {
    read -r line || return 1
    echo "$line"
    n=$(($1 - 1))
    while [[ $n -gt 0 ]] && read -r line; do
        echo "$line"
        n=$((n-1))
    done
}

然后你可以这样做:

n=20
foo.sh | while lines=$(read_n_lines $n); do
    printf "%s\n" "$lines" | bar.sh
done