
Я пытаюсь сравнить два 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 ..