我有一个部分重复记录的列表。每个唯一记录均由其前 5 个字段标识,但每个记录都有多个与其关联的“特征”,由后续 4 个字段的内容定义。每个记录的第一个字段中有一个“标识符”,但一个标识符可以有多个与之关联的记录。示例如下:
A 1 122114 A T ABCD c.123A>T 41 K/Y
A 1 122114 A T EFGH c.456-7890T>A . .
B 7 56715 G C IJKL c.321+9876C>A . .
B 7 56715 G C MNOP c.543G>C 181 Q/L
B 7 56715 G C PONM c.-7324G>C . .
C 12 9844 T C QRST c.8392-68723T>C . .
C 12 3338745 T C UVWX c.599A>G 200 P/*
C 21 71120 C G YZAB c.35C>G 12 D
C 21 71120 C G CDEF c.-2345G>C . .
D 1 122114 A T ABCD c.123A>T 41 K/Y
D 1 122114 A T EFGH c.456-7890T>A . .
E 8 5094 A AT GHIJ c.678_679insT 226-227 .
E 8 5094 A AT KLMN c.-2356_-2357insT . .
我希望将每个“记录”的文件过滤为一行,使用条件层次结构来过滤“功能”,例如:
- 字段 9 包含“/”,否则
- 字段 9 包含 [AZ],否则
- 字段 8 包含 [数字],否则
- 字段 7 包含“[范围从 -50 到 +50][A、C、T 或 G]”
一旦“记录”满足这些条件,我就不再希望它进一步(以避免每个“记录”获得超过一行)。
我尝试使用 awk 使用前 5 个字段创建一个数组并运行 for 循环,但我对其进行了一些哈希处理(请原谅双关语):
awk -F"\t" '{a[$1$2$3$4$5]=$0;{for (i in a) if ($9~"/") print a[i]; else if ($9~/[A-Z]/) print a[i]; else if ($8~/[0-9]/) print a[i]}}' file
这最终会重复打印多次。有没有办法在 awk 中做到这一点?
答案1
Perl 一行代码在这里:
perl -F'\t' -lane '$r{$F[0].$F[1].$F[2].$F[3].$F[4]}=$_ if $F[8]=~/\// or $F[8]=~[A-Z] or $F[7]=~/\d/ or $F[6]=~/\b(\d\d)[ACTG]/ and $1<=50; END{print $r{$_} for (keys %r)}' file
评论:
perl
假设它在您的系统上可用,则提供了一个解决方案。如果需要,应该很容易在 中重写awk
,因为逻辑和语法非常相似。
条件基于您的规格和awk
片段。正如评论中已经指出的那样,至少其中之一似乎不符合您的输入文件示例。
这最后的打印找到的具有相同密钥的记录。
记录按随机顺序打印。