Передача stdout двум различным командам - PullRequest
0 голосов
/ 29 апреля 2018

Я работал над этим весь день, вроде как заставил его работать, но мне все еще может понадобиться помощь, чтобы отшлифовать мой код.

Ситуация: Я использую bedtools , который получает два файла (с разделителями табуляции), которые содержат геномные интервалы (по одному на строку) с некоторыми дополнительными данными (по столбцам). Точнее, я запускаю функцию window , которая генерирует и выводит, который содержит для каждого интервала в файле "a" все интервалы в файле "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

Вопрос: Итак, дело в том, что я хочу использовать этот стандартный вывод , чтобы сделать несколько вещей за один выстрел.

  1. Подсчитать количество строк в исходном стандартном выводе. Для этого я использую wc -l
  2. Тогда:
    • вырезать колонны 4-6 cut -f 4-6
    • сортировать строки и сохранять только те, которые не повторяются sort | 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 или чего-либо еще.

Спасибо

1 Ответ

0 голосов
/ 29 апреля 2018

Когда вы создаете «разветвленный конвейер», подобный этому, bash должен запускать две половины вилки одновременно, иначе где он будет буферизовать стандартный вывод для другой половины вилки? По сути, это похоже на запуск обеих субоболочек в фоновом режиме, что объясняет, почему вы получаете результаты в порядке, которого вы не ожидали (из-за параллелизма), и почему выходные данные выводятся бесцеремонно в верхнюю часть вашей командной строки.

Вы можете избежать обеих этих проблем, записав два выходных данных в отдельные временные файлы, подождав, пока все закончится, и затем объединяя временные файлы в ожидаемом порядке, например так:

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
...