Сравнение двух tsv-файлов

Сравнение двух tsv-файлов

Я пытаюсь сравнить два tsv-файла. Файл для запроса (file1) выглядит так:

Chr      Start      End
chr1    234738546   234738934
chr1    234792654   234793537
chr1    234908151   234908864
chr1    235097868   235098170
chr1    236080566   236081347
chr1    240307621   240308262
chr1    240308207   240308637
chr1    240308546   240308962
chr1    242627058   242627262
chr1    243923195   243923709

Второй столбец другого файла (file2) содержит числа, которые я хочу проверить, лежат ли они между числами в столбце 2 и 3, и повторять это до тех пор, пока условие не будет выполнено.

например: 242627060лежит между 242627058&242627262

Файл2 выглядит так:

Chr    Centre_Coord Ignore_this_col   Secondary Information
chr1    234765055   234765056   NR_033927_LINC00184     .   +
chr1    234782033   234782034   NR_125944_LOC101927787  .   +
chr1    234859787   234859788   NR_038856_LINC01132     .   +
chr1    234895802   234895803   NR_148962_PP2672        .   -
chr1    235099745   235099746   NR_125945_LOC101927851  .   -
chr1    235324564   235324565   NR_144491_RBM34         .   -
chr1    235097888   235291252   NR_002956_SNORA14B      .   -
chr1    235097869   235353431   NR_039908_MIR4753       .   -
chr1    235324564   235324565   NR_027762_RBM34         .   -
chr1    235324564   235324565   NM_001346738_RBM34      .   -

и дает мне следующий вывод:

chr1:242627058-242627262,  242627060

где -разделенные координаты взяты из file1, а запятая отделена от второго столбца file2.

Я уже пробовал использовать awkцикл while, но по какой-то причине у меня не получилось этого сделать.

while read a b c; do col2=$b; col3=$3; tail -n +1 path/to/file2 | awk 'BEGIN{OFS="\t"}{if($2>=$col2 && $2<=$col3) {print $a,$col2,$col3,$2}; break; else continue}' > rohit_TSS.txt; done < file1 

решение1

Вероятно, проще сделать это в два этапа.

Закиньте все во вспомогательный файл и отсортируйте.

awk 'FNR>1{print $1, $2, $3, $4 }' file1 file2 | sort -k1 >> file3

Затем просто пройдитесь по ним awkза один проход.

awk '{if (NF == 3) {chr=$1; lo=$2; hi=$3} else { if ($1==chr && $2>=lo && $2<=hi) print $1":"lo"-"hi", "$2}}' file3

Прогулка по awk...... Вы знаете, откуда file3пришли строки file1, потому что у них всего 3 поля, file2есть и больше....

if (NF == 3) {chr=$1; lo=$2; hi=$3}

это тест, который истинен, когда вы находитесь на линии (в file3), которая пришла из file1. Каждый раз, когда вы находите линию из file1, то вы хотите получить значения loи hi, а также текущую хромосому

else  

В противном случае мы находимся на линии от file2так что просто...

 if ($1==chr && $2>=lo && $2<=hi) print $1":"lo"-"hi", "$2}

И если мы находимся в той же хромосоме, а интересующее нас значение $2находится между loи hiпределами, которые мы помним ранее, то мы печатаем в вашем формате.

Выход был

chr1:235097868-235098170, 235097869
chr1:235097868-235098170, 235097888

примечание

На самом деле вы можете забыть первое awkи просто

cat file1 file2 | sort > file3

А поскольку сортировка выполняется по всей строке, она должна быть chrагностичной.

решение2

for C in `cat file2 |awk -F" " '{ print $2 }' ` ; do 
   echo "Checking $C .." ;
   cat file1 | awk -v var=$C -F" " '{ if ( var  >=$2 && var <=$3 ) print $1":"$2"-"$3", "var  ;  }'; 
done

Позже вы можете удалить echo "Проверка $C .." ;

Checking 234765055 ..
Checking 234782033 ..
Checking 234859787 ..
Checking 234895802 ..
Checking 235099745 ..
Checking 235324564 ..
Checking 235097888 ..
chr1:235097868-235098170, 235097888
Checking 235097869 ..
chr1:235097868-235098170, 235097869
Checking 235324564 ..
Checking 235324564 ..

Связанный контент