根据扩展列值过滤 csv 文件

根据扩展列值过滤 csv 文件

我有以下 csv 文件:

ID,PDBID,FirstResidue,SecondResidue,ThirdResidue,FourthResidue,Pattern
RZ_AUTO_1,4tov,1404,1405,1518,1519,CG/AA Canonical ribose-zipper
RZ_AUTO_2,4tov,1405,1406,1517,1518,GU/AA Naked ribose-zipper
RZ_AUTO_3,4tov,1043,1044,1047,1048,CC/GA Naked ribose-zipper
RZ_AUTO_4,4tov,1556,1557,1514,1515,CC/GA Naked ribose-zipper
RZ_AUTO_5,4tow,130,131,99,100,AU/CA Canonical ribose-zipper
RZ_AUTO_6,4tow,766,767,1524,1525,AA/CG Canonical ribose-zipper
RZ_AUTO_7,4tow,131,132,98,99,UC/AC Canonical ribose-zipper

我需要遍历每一行并打印可以扩展 FirstResidue 和 SecondResidue 值的行(这意味着 SecondResidue 成为具有相同 PDBID 的不同行中的 FirstResidue)。例如,(行 RZ_AUTO_1 和行 RZ_AUTO_2)AND(行 RZ_AUTO_5 和行 RZ_AUTO_7)。输出应如下所示:

RZ_AUTO_1,4tov,1404,1405,1518,1519,CG/AA Canonical ribose-zipper
RZ_AUTO_2,4tov,1405,1406,1517,1518,GU/AA Naked ribose-zipper
RZ_AUTO_5,4tow,130,131,99,100,AU/CA Canonical ribose-zipper
RZ_AUTO_7,4tow,131,132,98,99,UC/AC Canonical ribose-zipper

是否可以使用 awk 或其他 UNIX 方法来做到这一点?我正在使用 OSX。

答案1

你可以试试这个:

$ sort -rt"," -k2,3 file.csv | 
   awk -F, '{a[$2][$3]=$0; if(a[$2][$4]){print a[$2][$4]; print;}}'
RZ_AUTO_7,4tow,131,132,98,99,UC/AC Canonical ribose-zipper
RZ_AUTO_5,4tow,130,131,99,100,AU/CA Canonical ribose-zipper
RZ_AUTO_2,4tov,1405,1406,1517,1518,GU/AA Naked ribose-zipper
RZ_AUTO_1,4tov,1404,1405,1518,1519,CG/AA Canonical ribose-zipper

解释

  • sort根据第二个和第三个字段对文件进行排序,以便具有相同 PDBID 的行被一起排序并根据功能的第一个残基的位置。-r反转排序(以便首先打印较大的数字),-t,将字段分隔符设置为,-k定义要排序的字段。

至于awk脚本:

  • -F,:将字段分隔符设置为,
  • a[$2][$3]=$0;:这是一个列表的列表,一个二维数组。例如,对于第一行,它将是a[4tov][1404]=$0.a只是数组的名称。该值设置为当前行$0
  • if(a[$2][$4]):如果发现第四个字段(第二个残基)与第一个残基具有相同的 PDBID。
  • print a[$2][$4]; print;:打印它所在的行(因为它被保存为数组的值a)和当前行。

我无法访问 OSX 进行检查,但基于你的评论,看起来 OSXawk与 不同GNU awk,不能处理多维数组。所以,Perl 中也有同样的事情:

sort -rt"," -k2,3 file.csv | 
 perl -F"," -ane '$k{$F[1]}{$F[2]}=$_; 
                  print "$k{$F[1]}{$F[3]}$_" if $k{$F[1]}{$F[3]}'

答案2

您可以使用文本查询像 SQL 数据库一样查询电子表格数据。

答案3

通过python3使用re模块。

#!/usr/bin/python3
import re
import sys
j = sys.argv[1]
with open(j) as f:
    fil = f.read()
m = re.findall(r'(?s)(?:^|\n)([^,]*,([^,]*),[^,]*,([^,]*)[^\n]*).*?\n([^,]*,\2,\3,[^\n]*)', fil)
for i in m:
    print(i[0]+'\n'+i[-1])

将以上代码保存在名为的文件中script.py,并通过在终端上运行以下命令来执行该文件。

python3 script.py inputfile

正则表达式演示

$ python3 script.py file.csv
RZ_AUTO_1,4tov,1404,1405,1518,1519,CG/AA Canonical ribose-zipper
RZ_AUTO_2,4tov,1405,1406,1517,1518,GU/AA Naked ribose-zipper
RZ_AUTO_5,4tow,130,131,99,100,AU/CA Canonical ribose-zipper
RZ_AUTO_7,4tow,131,132,98,99,UC/AC Canonical ribose-zipper

相关内容