如何为每个stdin行执行命令?

时间:2016-11-15 15:18:03

标签: bash

我有以下命令:

$ cmd-a | while read -r line; do echo "${line}"; cmd-b; done

这很好用,并且对于所有意图和目的看起来像cmd-a只是正常打印它的标准输出,但是对于每一行我们也执行cmd-b

有更简洁的方法吗?

cmd-a | xargs -n1 cmd-b会很好,但它会在所有空格上分裂(我知道GNU xargs有-d选项,但遗憾的是我无法使用它,并且会抑制输出cmd-a

1 个答案:

答案 0 :(得分:6)

现有的提案完全是惯用且干净的; BashFAQ #001建议使用相同的机制逐行迭代输入。没有理由替换它,但如果你经常使用它,那么封装它可能是有意义的。

考虑以下功能:

for_each_line() {
  while IFS= read -r line; do
    printf '%s\n' "$line"
    line=$line "$@"
  done
}

...此后运行:

cmd-a | for_each_line cmd-b

...或者,如果您的cmd-b是一个函数并且您希望它能够修改shell状态,则可以按如下方式调用上述内容(BashFAQ #24):

for_each_line cmd-b < <(cmd-a)

...如果有任何理由根据相同的值修改其行为,那么它将使前一行可用于环境中的cmd-b