列出特定列中的所有唯一字符串

列出特定列中的所有唯一字符串

我不知道巨大的 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

相关内容