我不知道巨大的 vcf.gz 文件中有什么,如下所示
CHROM POS ALT 12345
1 345632 T 0/1:4,4:8:99:105,0,106
4 032184 C 1/1:46,9:55:99:99,0,1222
6 843290 A 0/1:67,20:87:99:336,0,1641
7 743290 C 0/1:37,20:57:99:336,0,2641
8 329283 T 0/2:99:21:253,0,290:11,10
9 789320 C 2/2:99:21:253,0,290:11,10
我想提取所有独特的“:”之前的第四列中的值。在这种情况下就是这样:
0/1
1/1
0/2
2/2
你有什么建议吗?
答案1
使用awk
,检查第四列的格式是否正确:
awk 'match($4, /^[0-9]+\/[0-9]+:/) {
c = substr($4, RSTART, RLENGTH-1)
if (!seen[c]++) print c
}'
答案2
我们假设以字母开头的行是注释或被忽略。
zcat vcf.gz | awk \
'BEGIN {
RS = "[\t\v\f ]*(\r\n|\n\r|\r|\n)" ;
FS = "[\t\v\f ]+"
}
/^[A-Za-z]/ {
next
}
NF >= 4 {
key = $4 ;
sub(/:.*$/, "", key) ;
seen[key]++
}
END {
for (key in seen)
printf "%s\n", key
}'
您可以将整个命令写在一行上(\
不过,请删除第一行末尾的 ),因为我添加了所有必要的分号来执行此操作。
该BEGIN
规则设置了通用换行符支持。行尾的所有空格都将被忽略,任何换行符形式(CR、LF、CRLF、LFCR)都被接受为换行符。任意数量的制表符或空格都被视为字段分隔符。
该规则/^[A-Za-z]/
适用于以字母开头的所有行。这next
导致它们被忽略。
下一条规则适用于至少具有四个字段的所有记录(行)。第四个字段被复制到变量key
,然后第一个冒号(包括冒号)之后的所有内容都被删除。我们使用结果值作为关联数组的键seen
。我们分配的值并不重要,但这里seen[key]
将包含每个值被引用的次数(1 次或多次)。
该END
规则在处理完所有输入后运行。在这里,循环迭代seen[]
数组的键(以未指定的顺序),并仅打印键。
如果您想保留数据中的顺序,或者对键使用某种特定的顺序,则上面的代码片段需要稍作修改。
答案3
如果perl
没问题的话:
$ perl -lane '($k) = $F[3] =~ m/^([^:]+)/; print $k if !$seen{$k}++ && $. > 1' ip.txt
0/1
1/1
0/2
2/2
($k) = $F[3] =~ m/^([^:]+)/
:
获取第 4 列之前的字符串- 如果它是唯一的并且不是第一行,则打印(以避免标题)
如果之前的模式:
必须是模式digits/digits
,则将匹配更改为m|^(\d+/\d+):|
答案4
我会用:
grep -o -P '.{1}/.{1}' file
在你的情况下:
zcat vcf.gz | grep -o -P '.{1}/.{1}'
编辑:仅出现一次,在行末尾添加 uniq:
zcat vcf.gz | grep -o -P './.' |独特的
或者如果您想要按顺序排列:
zcat vcf.gz | grep -o -P './.' |排序-u