ubuntuusers.de

Abstand zwischen zwei Zeilen mit Perl-Skript ausgeben

Status: Ungelöst | Ubuntu-Version: Ubuntu 18.04 (Bionic Beaver)
Antworten |

linuxanfänger99

Anmeldungsdatum:
27. Mai 2019

Beiträge: Zähle...

Hallo,

Ich bin noch unerfahren im programmieren und habe ein Problem mit folgendem Perl-Skript:

 
open (INFILE, "$ARGV[0]");                     
open (OUTFILE, ">distance.txt");		
$count = 1;
@arr = <INFILE>;

while ($arr[$count-1] ne "" || $arr[$count] ne "")

{

($name1, $contigID1, $start1, $end1, $OrfID1, $strang1, $fam1, $Pfam_id1, $fam1, $e_value1, $gen_start1, $gen_end1,  $overlap1) = split ("\t", $array[$count-1], 12);
($name2, $contigID2, $start2, $end2, $OrfID2, $strang2, $fam2, $Pfam_id2, $fam2, $e_value2, $gen_start2, $gen_end2,  $overlap2) = split ("\t", $array[$count], 12);

if ($Pfam_id1 eq $Pfam_id2 && $contigId1 eq $contigID2)

{

$dist = ($start2 - $end1);

print OUTFILE ("$arr[$count-1], $dist\n");    									

}

$count++;

} 

Dieses möchte ich auf verschiedene Datensätze nach folgendem Aufbau anwenden:

 
Name=MT	NC_0077881	4904	4740	NC_0077881_49		+	COX1	PF0011520	21e-08	1	16234	164
, 0
Name=MT	NC_0077881	5219	5043	NC_0077881_51		+	COX1	PF0011520	11e-08	1	16234	176
, 0
Name=MT	NC_0077881	5369	5223	NC_0077881_53		+	COX1	PF0011520	86e-08	1	16234	146
, 0
Name=MT	NC_0077881	5525	5373	NC_0077881_56		+	COX1	PF0011520	81e-12	1	16234	152
, 0
Name=MT	NC_0077881	5630	5529	NC_0077881_57		+	COX1	PF0011520	65e-09	1	16234	101
, 0 

Statt der 0 sollte als neue zweite Zeile oder 13 Spalte nun die Distanz zwischen z.B. 5219 (Zeile 2) - 4740 (Zeile 1), also 479 stehen. Wo liegt der Fehler? Wie kann ich dies für jede Spalte hinbekommen? Vielen Dank für Eure Zeit und Hilfe!

Liebe Grüße

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13205

Du merkst Dir einfach den letzten Wert in einer Variablen die Du außerhalb des Schleifenrumpfes deklarierst und dann bei jedem Durchlauf der Schleife auf mit dem aktuellen Wert füllst.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Wenn das , 0 in einer eigenen Zeile steht, musst du in jedem Schritt zwei Zeilen weitergehen und die Felder mit den Werten aus zwei Zeilen vorher vergleichen. Dann scheinst du mir für die Distanz zwei Strings statt zwei Nummern voneinander abzuziehen - Perl liefert dafür 0 zurück. Außerdem hast du eine Mischung aus Unterschiedlichen Schreibweisen (z.B. contigID1 und contigId1) im Code.

Muss das unbedingt in Perl 5 passieren? Man könnte das z.B. in Python 3 so lösen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/env python3
import fileinput


def line_pairs():
    """
    generate tuples of two consecutive lines, advancing one by one
    skipping empty lines or lines starting with ','
    """
    last_line = None
    for line in fileinput.input():
        line = line.rstrip()
        if line and not line.startswith(','):
            if last_line:
                yield (last_line, line)
            last_line = line


with open('distance.txt', 'w') as output:
    for l1, l2 in line_pairs():
        _, contigID1, start1, end1, _, _, _, Pfam_id1, *_ = filter(None, l1.split('\t'))
        _, contigID2, start2, end2, _, _, _, Pfam_id2, *_ = filter(None, l2.split('\t'))
        if Pfam_id1 == Pfam_id2 and contigID1 == contigID2:
            dist = str(int(start2) - int(end1))
        else:
            dist = 0
        print(l1.rstrip(), dist, sep='\t', file=output)
    print(l2, "0", sep='\t', file=output)                

Das gibt für deine Beispieldaten folgendes aus:

$ python3 calculate_distance.py data.tsv
$ cat distance.txt
Name=MT	NC_0077881	4904	4740	NC_0077881_49		+	COX1	PF0011520	21e-08	1	16234	164	479
Name=MT	NC_0077881	5219	5043	NC_0077881_51		+	COX1	PF0011520	11e-08	1	16234	176	326
Name=MT	NC_0077881	5369	5223	NC_0077881_53		+	COX1	PF0011520	86e-08	1	16234	146	302
Name=MT	NC_0077881	5525	5373	NC_0077881_56		+	COX1	PF0011520	81e-12	1	16234	152	257
Name=MT	NC_0077881	5630	5529	NC_0077881_57		+	COX1	PF0011520	65e-09	1	16234	101	0 
Antworten |