ubuntuusers.de

Zeilenduplikate für bestimmte Spalten mit awk selektieren

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

linuxanfänger99

Anmeldungsdatum:
27. Mai 2019

Beiträge: Zähle...

Hallo,

ich hoffe ihr könnt mir weiterhelfen, ich bin leider noch sehr unerfahren mit Linux und der Programmierung generell. Ich habe folgende Datei (erste Zeilen: https://paste.ubuntuusers.de/423879/), die nach folgendem Schema aufgebaut ist:

NC_022830.1     2892    2626    NC_022830.1_23  .       +       Proton_antipo_M PF00361.20      0.0032  2434    16339   Name=ND5
        266

Ich möchte die Datei nun zeilenweise durchgehen und dabei die Daten herausfiltern, die die gleichen Pfam-Domänen ( Spalte 8) und die gleiche genomische Lokation (Spalte 10 und 11) haben. Ein erster Versuch dies mit awk zu programmieren war nicht erfolgreich

cat Agropora_test.txt | while read line; do awk' { if ($2 eq $2 && $3 eq $3  && $8 eq $8); print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12 }'; done 

Dabei können eine unterschiedliche Anzahl von Zeilen einer einzelnen Pfam-Domäne und genomischer Lokation zugeordnet sein, die Zeilen müssen also einzeln durchgegangen werden ( vielleicht mit for-Bedingung nN=$(nN+1))? Kann mir da jemand weiterhelfen?

Prof._Frink

Anmeldungsdatum:
29. Mai 2010

Beiträge: 1096

Hi,

das geht auch kürzer.

  1. cat brauchst du nicht, weil awk die Daten selbst einlesen kann.

  2. while brauchst du nicht, weil awk die Zeilen sowieso sequentiell einliest.

  3. Den print Befehl kann am verkürzen.

Das in Code:

$ awk  '{ if ($2 eq $2 && $3 eq $3  && $8 eq $8); print $0}' daten.txt
NC_022830.1     2892    2626    NC_022830.1_23  .       +       Proton_antipo_M PF00361.20      0.0032  2434    16339   Name=ND5      266 

LG,

Frink

EDIT: Achso, sorry, dachte deine if-Abfrage wäre richtig und habe sie nur kopiert, aber das ist sie nicht, deshalb brauche ich kurz, um den Code anzupassen, einen Moment...

Prof._Frink

Anmeldungsdatum:
29. Mai 2010

Beiträge: 1096

Alter, war das kompliziert, es hat mich eine Ewigkeit gekostet, das in AWK hinzubekommen und es geht MIT SICHERHEIT einfacher, aber zumindest funktioniert meine Lösung

test.txt:

NC_022830.1 2892 2626 NC_022830.1_23 . + Proton_antipo_M PF00361.20 0.0032 2434 16339 Name=ND5 266
NC_022830.1 2892 2626 NC_022830.1_23 . + Proton_antipo_M PF00361.20 0.0032 2434 16339 Name=ND5 266
1 2 3 4 5 6 7 8 9 10 11 12 13
0 1 2 3 4 5 6 8 8 10 11 11 12
1 2 3 4 5 6 7 PF00361.20 16339 2434 16339 2 2
0 0 0 0 0 0 0 0 0 0 0  0 0

test.awk:

 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
NR == 1{
    fields = NF
n}

{
    if ( NF == fields )
    {
	for (x = 1; x <= NF; x++)
	{
	    
	    array [x","NR] = $x
	    split(x","NR,zz,",")
	}
    }

    


}

END{
    for (x1 in array){
        split(x1,indizes1,",")

	for (x2 in array){
	    split(x2,indizes2,",")

	    if ( indizes1[2] == indizes2[2])
		continue
	    
	    if (  array[8","indizes1[2]] == array[8","indizes2[2]] &&  array[10","indizes1[2]] == array[10","indizes2[2]] && array[11","indizes1[2]] == array[11","indizes2[2]])
	    {
				    if ( !(indizes1[2] in printed) )
					{

				    for ( i=1;i<=fields;i++)
				    {
					ORS=""
					print(array[i","indizes1[2]]" ")
					    printed[indizes1[2]] = 1

					}
					
				    ORS="\n"
				    print("")
							    
				    
				}
	    			    }
		    }
    }
    
}

Aufruf und Ausgabe:

$ awk -f test.awk test.txt  
NC_022830.1 2892 2626 NC_022830.1_23 . + Proton_antipo_M PF00361.20 0.0032 2434 16339 Name=ND5 266 
NC_022830.1 2892 2626 NC_022830.1_23 . + Proton_antipo_M PF00361.20 0.0032 2434 16339 Name=ND5 266 
1 2 3 4 5 6 7 8 9 10 11 12 13 
0 1 2 3 4 5 6 8 8 10 11 11 12 
1 2 3 4 5 6 7 PF00361.20 16339 2434 16339 2 2  

Haha, ich hoffe, es gefällt dir.

LG,

Frink

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

Wenn ich dich richtig verstehe, willst du Grüppchen bilden, also deine Daten zusammenfassen, wenn drei Felder übereinstimmen - das könnte man mit Python3 z.B. so machen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/usr/bin/env python3
import fileinput
from collections import defaultdict

collection = defaultdict(list)
for line in fileinput.input():
    fields = line.split()
    try:
        collection[(fields[7], fields[9], fields[10])].append(line) # Indices start at zero
    except IndexError:
        pass

for c in collection.values():
    print('*' * 50)
    for e in c:
        print(e, end='')
./group_data.py Agropora_test2.array
**************************************************
NC_022830.1     2892    2626    NC_022830.1_23  .       +       Proton_antipo_M PF00361.20      0.0032  2434    16339   Name=ND5 266
NC_022830.1     3129    2896    NC_022830.1_24  .       +       Proton_antipo_M PF00361.20      1.8e-13 2434    16339   Name=ND5 233
**************************************************
NC_022830.1     2892    2626    NC_022830.1_23  .       +       Proton_antipo_M PF00361.20      0.0032  2434    3153    Name=YP_008815465.1     266
NC_022830.1     3129    2896    NC_022830.1_24  .       +       Proton_antipo_M PF00361.20      1.8e-13 2434    3153    Name=YP_008815465.1     233
**************************************************
NC_022830.1     2892    2626    NC_022830.1_23  .       +       Proton_antipo_M PF00361.20      0.0032  1       18479   Name=MT 266
NC_022830.1     3129    2896    NC_022830.1_24  .       +       Proton_antipo_M PF00361.20      1.8e-13 1       18479   Name=MT 233
**************************************************
NC_022830.1     2892    2626    NC_022830.1_23  .       +       Proton_antipo_N PF00662.20      4.4e-17 2434    16339   Name=ND5 266
**************************************************
NC_022830.1     2892    2626    NC_022830.1_23  .       +       Proton_antipo_N PF00662.20      4.4e-17 2434    3153    Name=YP_008815465.1     266
**************************************************
NC_022830.1     2892    2626    NC_022830.1_23  .       +       Proton_antipo_N PF00662.20      4.4e-17 1       18479   Name=MT 266
**************************************************
NC_022830.1     3749    3453    NC_022830.1_29  .       +       NADHdh  PF00146.21      8.1e-27 2434    16339   Name=ND5        296 

linuxanfänger99

(Themenstarter)

Anmeldungsdatum:
27. Mai 2019

Beiträge: 4

Vielen Dank Prof._Frink und seahawk1986 für die Mühe die ihr euch gemacht habt und die ausführlichen Lösungen!

Ich kenne mich mit Phyton nicht wirklich aus, aber der Output sieht gut aus. Leider bekomme ich meine Daten nicht importiert:

 >>> import Agropora_test.txt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'Agropora_test' 

An Prof._Frink, ich hatte an genau solche Schleifen gedacht. Allerdings brauche ich die Indexierung nicht. Im Output sollte rechts die Pfam-Domäne mit dem Namen stehen ( Spalte 7 und 8 ) nach den unterschiedlichen genomischen Lokalisierungen sortiert. Links stehen im Wesentlichen die ORFs ( Spalte 4 ). Entschuldigung wenn ich das nicht klar ausgedrückt habe! Wie könnte man den Code anpassen?

Liebe Grüße

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

linuxanfänger99 schrieb:

Ich kenne mich mit Phyton nicht wirklich aus, aber der Output sieht gut aus. Leider bekomme ich meine Daten nicht importiert:

 >>> import Agropora_test.txt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'Agropora_test' 

Du musst eigentlich nur das Skript ausführbar machen, das ich gepostet hatte, und es dann mit der oder den gewünschten Dateien als Argument aufrufen. Eine interaktive REPL-Sitzung braucht es dafür nicht und import ist ausschließlich für Python-Code gedacht, nicht für beliebige Dateien.

linuxanfänger99

(Themenstarter)

Anmeldungsdatum:
27. Mai 2019

Beiträge: 4

Vielen Dank seahawk1986, das Skript hat funktioniert!

Antworten |