
Ich versuche, zwei TSV-Dateien zu vergleichen. Die abzufragende Datei (Datei1) sieht folgendermaßen aus:
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
Die zweite Spalte einer anderen Datei (Datei2) enthält Zahlen, bei denen ich überprüfen möchte, ob sie zwischen den Zahlen in Spalte 2 und 3 liegen, und dies wiederholen möchte, bis die Bedingung erfüllt ist.
zB: 242627060
liegt zwischen 242627058
&242627262
Datei2 sieht so aus:
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 . -
und gibt mir die folgende Ausgabe:
chr1:242627058-242627262, 242627060
woher die -
getrennten Koordinaten stammen file1
und die durch Kommas getrennte zweite Spalte von file2
.
Ich habe bereits versucht, awk
eine While-Schleife zu verwenden, aber aus irgendeinem Grund hat es nicht geklappt.
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
Antwort1
Wahrscheinlich ist es einfacher, dies in zwei Schritten zu erledigen.
Werfen Sie alles in eine Hilfsdatei und sortieren Sie es.
awk 'FNR>1{print $1, $2, $3, $4 }' file1 file2 | sort -k1 >> file3
Dann durchlaufen Sie sie einfach awk
in einem Durchgang.
awk '{if (NF == 3) {chr=$1; lo=$2; hi=$3} else { if ($1==chr && $2>=lo && $2<=hi) print $1":"lo"-"hi", "$2}}' file3
Ein Spaziergang durch die awk
…… Sie wissen, welche Zeilen in file3
stammen, file1
weil sie nur 3 Felder haben, file2
also mehr …
if (NF == 3) {chr=$1; lo=$2; hi=$3}
ist ein Test, der wahr ist, wenn Sie sich auf einer Linie (in file3
) befinden, die von stammt file1
. Jedes Mal, file1
wenn Sie eine Linie von finden, möchten Sie die Werte lo
und hi
sowie das aktuelle Chromosom erhalten
else
Ansonsten sind wir von file2
daher einfach auf einer Linie.....
if ($1==chr && $2>=lo && $2<=hi) print $1":"lo"-"hi", "$2}
Und wenn wir uns im selben Chromosom befinden und der Wert von Interesse $2
zwischen den lo
und hi
Grenzen liegt, an die wir uns von vorher erinnern, drucken wir in Ihrem Format.
Die Ausgabe war
chr1:235097868-235098170, 235097869
chr1:235097868-235098170, 235097888
Notiz
Tatsächlich können Sie das erste awk
und
cat file1 file2 | sort > file3
Und da die Sortierung auf der gesamten Zeile erfolgt, sollte es chr
agnostisch sein.
Antwort2
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
Später können Sie das Echo „Checking $C ..“ entfernen.
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 ..