根據行中的連續數字過濾 .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(第三個字段)和 Second_Residue($5)的數量連續)和(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

如果要比較的每個欄位都有一個非數字前綴字元(CA在您的範例中),那麼您應該能夠直接在 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

弱點

需要進一步加強的一個領域是對比賽的選擇grep。這可能會導致當前形式的誤報。使用諸如之類的工具或透過增強用於匹配線條的awk圖案可以更好地完成此操作。grep

相關內容