2017-11-20 6 views
0

Ich habe die folgende Datei mit n Reihen:Zeilen löschen, die Muster von ID übereinstimmen

>name.1_i4_xyz_n 
>name.1_i1_xyz_n 
>name.1_i1_xyz_n 
>name.1_i1_xyz_m 
>name.1_i2_xyz_n 
>name.1_i2_xyz_m 
>name.1_i7_xyz_m 
>name.1_i4_xyz_n 
... 

Ich möchte Zeilen löschen, die mit m endet. Im Beispiel wäre die Ausgabe:

>name.1_i4_n 
>name.1_i4_n 
... 

Bitte beachte, dass ich i2 gelöscht haben, da es zwei Datensätze hat und einer von ihnen endet mit m. Gleiches mit i1.

Irgendwelche Hilfe? Ich möchte es einfach halten und mache es mit nur einer Codezeile. Das ist, was ich habe, so weit:

$ grep "i._.*." < input.txt | sort -k 2 -t "_" | cut -d'_' -f1,2,4 
>name.1_i1_m 
>name.1_i1_n 
>name.1_i1_n 
>name.1_i2_m 
>name.1_i2_n 
>name.1_i4_n 
>name.1_i4_n 
>name.1_i7_m 
... 
+0

ja, alle von ihnen beginnen mit '>' – benhid

+0

Oder um es anders zu setzen Sie wollen _i4? –

Antwort

1

Wenn der i... Teil in jeder anderen Spalte nicht erscheint, Sie

grep -vFf <(grep -E 'm$' file | cut -d _ -f 2) file 

Der Teil innerhalb <() alle ausfiltert verwenden können i..., die eine Zeile mit m enden. In Ihrem Beispiel: i1, i2 und i7.

Die äußere grep nimmt eine Liste von literalen Suchzeichenfolgen (innerhalb der <()) und druckt nur die Zeilen, die keine der Suchzeichenfolgen enthalten.

+1

@anubhava Deshalb habe ich »* If the i ... Teil erscheint in keiner anderen Spalte * «. – Socowi

2

Zeilen zu löschen, die mit m endet:

$ grep -v m$ file 
>name.1_i4_xyz_n 
>name.1_i1_xyz_n 
>name.1_i1_xyz_n 
>name.1_i2_xyz_n 
>name.1_i4_xyz_n 

Eine andere Lösung, die die IDs Griffe, awk und 2 läuft mit:

$ awk 'BEGIN { FS="_" } # set delimiter 
NR==FNR {    # on the first run 
    if($0~/m$/)   # if it ends in an m 
     d[$2]   # make a del array entry of that index 
    next 
} 
($2 in d==0)' file file # on the second run don't print if index in del array 
>name.1_i4_xyz_n 
>name.1_i4_xyz_n 

Einzeilige Version:

$ awk 'BEGIN{FS="_"}NR==FNR{if($0~/m$/)d[$2];next}($2 in d==0)' file file 
+2

aber alle Zeilen, die 'i1' enthalten, sollten auch gelöscht werden, da es eine Zeile mit der ID' i1' gibt und mit 'm' endet (gleich mit' i2') – benhid

1

Sie awk wie diese verwenden:

awk -F_ '{if(/m$/) a[$2]; else rows[++n]=$0} 
END{for (i=1; i<=n; i++) {split(rows[i], b, FS); if (!(b[2] in a)) print}}' file 

>name.1_i4_xyz_n 
>name.1_i4_xyz_n 
0

Ein weiterer awk Vorschlag.

awk '/_i4/&&!/_m$/' filterm.awk 

>name.1_i4_xyz_n 
>name.1_i4_xyz_n 
Verwandte Themen