根据行中的连续数字过滤 .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

相关内容