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 ( C
oder A
in 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 sed
und 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 grep
Zeile. Dies kann in der aktuellen Form zu Fehlalarmen führen. Dies kann mit einem Tool wie awk
oder durch Verbesserung des Musters, das grep
zum Abgleichen der Zeilen verwendet wird, besser erreicht werden.