Filtern einer CSV-Datei basierend auf aufeinanderfolgenden Zahlen in einer Zeile

Filtern einer CSV-Datei basierend auf aufeinanderfolgenden Zahlen in einer Zeile

Ich habe eine CSV-Datei wie folgt:

                 1st       2nd      3rd       4th
   ID      ...   Res       Res      Res       Res        (other columns) ...

RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper
RZ_AUTO_4, 1ffk, C2767, 0, C2682, 0, G2679, 0, A2681, 0, CC/GA Naked ribose-zipper
RZ_AUTO_5, 1ffk, G2574, 0, C2575, 0, G2798, 0, A2776, 0, GC/GA Single ribose-zipper

Ich möchte Zeilen extrahieren, bei denen (die Anzahl von First_Residue (das dritte Feld) und Second_Residue ($5) aufeinander folgen) UND (die Anzahl von Third_Residue ($7) und Fourth_Residue ($9) aufeinander folgen). Ein Beispiel für eine Ausgabe wäre wie folgt:

RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper

Die Zeilen 4 und 5 werden entfernt, da die Restnummern nicht aufeinander folgen.

Wie kann ich dies mit awk oder sed tun?

Antwort1

Wenn jedes der zu vergleichenden Felder ein einzelnes nicht numerisches Präfixzeichen hat ( Coder Ain Ihrem Beispiel), dann sollten Sie in der Lage sein, die numerischen Teilzeichenfolgen direkt in awk zu extrahieren und zu vergleichen, z. B.

$ awk -F"[ \t,]+" 'substr($5,2)+0==substr($3,2)+1 && substr($9,2)+0==substr($7,2)+1' file.csv
RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper 
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper 
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper

Antwort2

Wenn Sie Folgendes verwenden können perl:

$ perl -F, -anle '
    map { s/\D//g } @F;
    print if ++$F[2] == $F[4] and ++$F[6] == $F[8];
' file
RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper

Antwort3

Dieses Bash-Skript macht, was Sie wollen, verwendet aber nicht nur sedund awk. Ich bin sicher, wenn mehr Zeit in die Entwicklung investiert würde, könnte es noch weiter verfeinert werden, aber es macht im Großen und Ganzen, was Sie wollen.

$ more cmd.bash 
#!/bin/bash

while read line; do 
    f1=$(echo "$line" | awk -F", " '{print $3}')
    f2=$(echo "$line" | awk -F", " '{print $7}')
    echo "$line" | grep  "${f1}.*$(expr ${f1:2} + 1).*${f2}.*$(expr ${f2:2} + 1)"
done <file

Beispielausführung

$ ./cmd.bash 
RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper

Schwächen

Ein Bereich, in dem es noch weiter verbessert werden muss, ist die Auswahl der Übereinstimmungen in der grepZeile. Dies kann in der aktuellen Form zu Fehlalarmen führen. Dies kann mit einem Tool wie awkoder durch Verbesserung des Musters, das grepzum Abgleichen der Zeilen verwendet wird, besser erreicht werden.

verwandte Informationen