我有两个程序在stdout上生成数据,我希望将paste
输出放在一起。我可以成功地这样做:
paste <(./prog1) <(./prog2)
但是我发现这个方法会打印两个输入的所有行,
我真正想要的是在输入程序完成后停止paste
。
因此,如果./prog1
产生输出:
a
b
c
但./prog2
产生:
Hello
World
我希望输出:
a Hello
b World
另请注意,其中一个输入程序实际上可能会产生无限输出,我希望能够处理这种情况。例如,如果我的输入是yes
和./prog2
,我应该得到:
y Hello
y World
答案 0 :(得分:3)
使用join
代替Schwartzian transform:
numbered () {
nl -s- -ba -nrz
}
join -j 1 <(prog1 | numbered) <(prog2 | numbered) | sed 's/^[^-]*-//'
每行输入nl
个数字,join -1 1
将使用相同的数字加入相应的行。较长文件中的额外行将没有连接伙伴并被省略。完成join
后,通过sed
管道移除行号。
答案 1 :(得分:2)
考虑使用awk:
awk 'FNR==NR{a[++i]=$0;next} FNR>i{exit}
{print a[FNR], $0}' <(printf "hello\nworld\n") <(printf "a\nb\nc\n")
hello a
world b
将较长的输出生成程序作为第二个输入。
答案 2 :(得分:2)
这是一个解决方案:
while IFS= read -r -u7 a && IFS= read -r -u8 b; do echo "$a $b"; done 7<$file1 8<$file2
如果输入文件的最后一行没有以换行符终止(但这样的文件不是有效的文本文件),这会产生稍微烦人的效果。
你可以将它包装在一个函数中,当然:
paste_short() {
(
while IFS= read -r -u7 a && IFS= read -r -u8 b; do
echo "$a $b"
done
) 7<"$1" 8<"$2"
}