Wie sortiert man nach ungeraden Zeilen und entfernt dann wiederholte Werte?

Wie sortiert man nach ungeraden Zeilen und entfernt dann wiederholte Werte?

Ich habe folgenden Dateityp:

transcr_25793 +
YAL039C -
transcr_25793 +
YAL037C-B -
transcr_20649 +
YBL100C -
transcr_7135 +
YBL029C-A -
transcr_11317 +
YBL067C -
transcr_25793 +
YAL038W +
transcr_7135 +
YBL029W +

Ich habe versucht, so etwas zu bekommen:

transcr_7135 +
YBL029C-A -
transcr_7135 +
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL039C -
transcr_25793 +
YAL037C-B -
transcr_25793 +
YAL038W +

Anschließend habe ich nach so etwas gesucht:

transcr_7135 +
YBL029C-A -
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL039C -
YAL037C-B -
YAL038W +

Ich habe das Handbuch und einige Beiträge durchgescrollt sort, konnte aber nichts finden, das auch nur annähernd dazu passt. Ich sortverwende einfach numerische Werte, um ungerade Zeilen zu erhalten ...

Antwort1

Reine gawkLösung:

awk -F_ 'NR%2{i=$2;next}{a[i]=a[i]"\n"$0}
         END{PROCINFO["sorted_in"]="@ind_num_asc";
             for(i in a) printf "%s","transcr_"i""a[i]"\n"}' file

Der Trick besteht darin, die Indizes des Arrays amit ein wenig Hilfe gawkdes speziellen PROCINFO-Arrays numerisch zu sortieren.

transcr_7135
YBL029C-A -
YBL029W +
transcr_11317
YBL067C -
transcr_20649
YBL100C -
transcr_25793
YAL039C -
YAL037C-B -
YAL038W +

Übrigens ist es schade, dass awk keine Option zum natürlichen Sortieren bietet, auch bekannt alsVersionssortierung(laut Text mit Zahlen).

Antwort2

Nicht genau die Sortierreihenfolge, die Sie angezeigt haben, aber vielleicht auch richtig?

$ cat input.txt|paste - -| sort -k1,1V -k2,2| tr "\t" "\n" | awk '{if($0 in line == 0) {line[$0]; print}}'
    transcr_7135 +
    YBL029C-A -
    YBL029W +
    transcr_11317 +
    YBL067C -
    transcr_20649 +
    YBL100C -
    transcr_25793 +
    YAL037C-B -
    YAL038W +
    YAL039C -

BEARBEITEN:

Geben Sie die Zeilennummer ein und verwenden Sie sie als Sortierschlüssel. Das Ergebnis sollte genau die Ausgabe sein, die Sie möchten:

$ cat input.txt | paste - - | nl | sort -k2,2V -k1,1g | cut -f2- | tr "\t" "\n" | awk '{if($0 in line == 0) {line[$0]; print}}'

Antwort3

Mit GNU sortund vorausgesetzt, die Zeilen enthalten keine TAB-Zeichen:

paste - - < file | sort -V | tr '\t' '\n' | awk '!seen[$0]++'

Oder sort -t$'\t' -sk1,1Vum die ursprüngliche Reihenfolge für Einträge mit identischen ungeraden Zeilen wie in Ihrer erwarteten Ausgabe beizubehalten.

Wenn Sie nicht über GNU verfügen sortund davon ausgehen, dass die ungeraden Zeilen immer diesem Muster folgen, können Sie es sort -Vdurch ersetzen sort -k1.9n.

Antwort4

Vor- und Nachbearbeitung mit awk; ​​dabei wird nicht davon ausgegangen, dass auf eine transcrZeile nur eine Zeile folgt Y*; es ist außerdem idempotent – ​​die Ausgabe könnte als Eingabe zurückgeleitet werden und würde das gleiche Ergebnis liefern.

awk '{print $0~/^transcr/ ? t=$0 : t" "$0}' /tmp/foo | sort -t_ -k2n -k2 -u | awk '{print (NF > 2) ? $3" "$4 : $0}'
transcr_7135 +
YBL029C-A -
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL037C-B -
YAL038W +
YAL039C -

verwandte Informationen