Bash 管道标准输出到两个不同的命令

Bash 管道标准输出到两个不同的命令,bash,shell,command-line,pipe,tee,Bash,Shell,Command Line,Pipe,Tee,我花了一整天的时间在这上面,有点让它运行起来了,但是我可能仍然需要一些帮助来完善我的代码语言 情境:我正在使用bedtools,它将两个包含基因组间隔的文件用制表符分隔,每行一个,并按列列出一些额外的数据。更准确地说,我运行的是window函数,它生成并输出一个文件中的每个间隔,b文件中的所有间隔都属于我用参数-l和-r定义的窗口。可以找到更精确的解释 从他们的网站上获取的功能示例: $ cat A.bed chr1 1000 2000 $ cat B.bed chr1 500 80

我花了一整天的时间在这上面,有点让它运行起来了,但是我可能仍然需要一些帮助来完善我的代码语言

情境:我正在使用bedtools,它将两个包含基因组间隔的文件用制表符分隔,每行一个,并按列列出一些额外的数据。更准确地说,我运行的是window函数,它生成并输出一个文件中的每个间隔,b文件中的所有间隔都属于我用参数-l和-r定义的窗口。可以找到更精确的解释

从他们的网站上获取的功能示例:

$ cat A.bed
chr1  1000  2000

$ cat B.bed
chr1  500   800
chr1  10000 20000

$ bedtools window -a A.bed -b B.bed -l 200 -r 20000
chr1  1000   2000  chr1  10000  20000

$ bedtools window -a A.bed -b B.bed -l 300 -r 20000
chr1  1000   2000  chr1  500    800
chr1  1000   2000  chr1  10000  20000
问题:所以我想用这个stdout一次性完成很多事情

计算原始标准输出中的行数。为此,我使用wc-l 然后: 切割柱4-6切割-f 4-6 对行进行排序,仅保留未重复排序的行| uniq-u 保存到文件tee file.bed 再次计算新标准输出的行数wc-l 因此,我设法让它或多或少地通过以下方式工作:

windowBed -a ARS_saccer3.bed -b ./Peaks/WTappeaks_-Mit_sorted.bed -r 0 -l 10000 | tee >(wc -l) >(cut -f 7-13 | sort | uniq -u | tee ./Window/windowBed_UP10.bed | wc -l)
这种方法很有效,因为我正确地获得了输出文件,并且值显示在屏幕上,但是。。。像这样

juan@juan-VirtualBox:~/Desktop/sf_Biolinux_sf/IGV/Collisions$ 448
543
第一个数字是第二个wc-l,我不明白为什么它显示第一个。而且,在第二个数字之后,游标仍在等待指令,而不是出现新的命令行,因此我假设代码行现在还没有完成。 这可能是一些非常基本的东西,但我将非常感谢任何人关心解释我多一点关于编程。 对于任何愿意提供解决方案的人,请记住,我希望将此管道保持在一条管线中,而不需要运行额外的sh或其他任何东西


谢谢当您创建这样的分叉管道时,bash必须同时运行分叉的两半部分,否则它会在哪里为分叉的另一半缓冲标准输出?因此,它本质上类似于在后台运行这两个子shell,这解释了为什么由于并发性,您会以预期的顺序获得结果,以及为什么输出会不规则地转储到命令提示符上

通过将两个输出写入单独的临时文件,等待所有操作完成,然后按预期顺序连接临时文件,可以避免这两个问题,如下所示:

windowBed -a ARS_saccer3.bed -b ./Peaks/WTappeaks_-Mit_sorted.bed -r 0 -l 10000 | tee >(wc -l >tmp1) >(cut -f 7-13 | sort | uniq -u | tee ./Window/windowBed_UP10.bed | wc -l >tmp2)
wait
cat tmp1 tmp2
rm tmp1 tmp2

我很难找到记录这一点的地方,但我认为等待只会导致一个进程替换—最近的一个?被包括在等待将等待的进程集中。Bash现在允许等待最新的进程替换,因为它显示为$!。从4.4的发行说明中