行内の連続した数字に基づいて .CSV ファイルをフィルタリングする

行内の連続した数字に基づいて .CSV ファイルをフィルタリングする

次のような CSV ファイルがあります。

                 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

私がやりたいのは、(First_Residue (3 番目のフィールド) と Second_Residue ($5) の数が連続している) AND (Third_Residue ($7) と Fourth_Residue ($9) の数が連続している) 行を抽出することです。出力の例は次のようになります。

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

残基番号が連続していないため、行 4 と 5 は削除されます。

awk または sed を使用してこれを実行するにはどうすればよいですか?

答え1

比較する各フィールドに数値以外のプレフィックス文字が1つある場合(CまたはA例では)、awkで直接数値部分文字列を抽出して比較できるはずです。例:

$ 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

答え2

使用できる場合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

答え3

この Bash スクリプトは、 と だけを使用していないものの、必要なことを実行しますsedawk開発にもっと時間を費やせば、さらに改良できると思いますが、おおよそ必要なことを実行します。

$ 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

実行例

$ ./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

弱点

さらに強化する必要がある領域の 1 つは、行内の一致の選択です。現在の形式では、誤検出が発生する可能性があります。これは、 などのツールを使用するか、行の一致に使用しているパターンを強化することで、grepより適切に行うことができます。awkgrep

関連情報