将stdout管道化为两个不同的命令

时间:2018-04-29 17:57:06

标签: bash shell command-line pipe tee

整天都在努力,有点运行,但我可能仍然需要一些帮助来改进我的代码语言。

情况:我正在使用 bedtools 获取两个文件(制表符分隔),其中包含基因组间隔(每行一个)和一些其他数据(按列)。更确切地说,我正在运行 window 函数,这将生成并输出包含" a"文件," b"中的所有间隔;属于我使用参数 // Get Product model var Product = require('../models/product'); // Get Product model var Category = require('../models/category'); /* * Get products index */ router.get('/',function(req,res){ var count; models.Product.count(function(c){ count=c; }) //models.product.find models.Product.find({ attributes: ['id','title','slug','desc','category','price','images'] }) .then(function(products){ res.render('admin/products',{ products:products, count:count }); }); }); /* * GET add product */ router.get('/add-product', function (req, res) { var title = ""; var desc = ""; var price = ""; models.Category.find({ attributes:['id','title','slug'] }) //.then((categories)=>{ both are giving same errors .then(function(categories){ res.render('admin/add_product', { title: title, desc: desc, categories: categories, price: price }); }); }); -l定义的窗口的文件。可以找到更精确的解释here

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

-r

问题:所以问题是我想用标准删除一次性完成很多事情。

  1. 计算原始标准输出中的行数。为此,我使用$ 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
  2. 然后:
    • 切割列4-6 wc -l
    • 对行进行排序并仅保留不重复的cut -f 4-6
    • 保存到文件sort | uniq -u
    • 再次计算新标准输出的行数tee file.bed
  3. 所以我已经做好了或多或少的工作:

    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 我不明白为什么它首先显示。而且,在第二个数字之后,光标仍然在等待指令而不是出现一个新的命令行,所以我假设现在还有一些代码行尚未完成。 这可能是非常基本的东西,但我会非常感谢任何关心编程的人。 对于任何愿意提供解决方案的人,请记住我希望将此管道保持在一行中,而无需再运行其他sh或其他任何内容。

    由于

1 个答案:

答案 0 :(得分:1)

当你创建一个"分叉的管道"像这样,bash必须同时运行fork的两半,否则它会在哪里缓冲另一半fork的stdout?所以它实际上就像在后台运行两个子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