我有以下命令:
$ 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
。
答案 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
。