首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用awk在每列中显示唯一值

使用awk在每列中显示唯一值
EN

Stack Overflow用户
提问于 2016-08-22 22:31:43
回答 3查看 1.1K关注 0票数 3

我是一个使用awk/grep等工具的新手,我想过滤一些数据。我有一个很大的电子表格,我想要一列一列地显示唯一值。例如,我想要更改以下内容:

代码语言:javascript
复制
DS571187    DS571220    DS571200    DS571194  
contig1     contig3     contig4     contig7  
contig2     contig3     contig4     contig7  
contig1     contig4     contig6     contig8  
contig1     contig5     contig6     contig9  
contig2     contig4     contig6     contig9  
contig2         
contig2 

类似下面这样的东西:

代码语言:javascript
复制
DS571187    DS571220    DS571200    DS571194
contig1     contig3     contig4     contig7
contig2     contig4     contig6     contig8
            contig5                 contig9     

基本上,我尝试将每一列作为其自己的列表进行排序,并以这种方式获得唯一值。任何帮助都将不胜感激。

琥珀色

EN

回答 3

Stack Overflow用户

发布于 2016-08-22 22:48:42

假设您的输入文件是以制表符分隔的,如下所示:

代码语言:javascript
复制
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
    for (colNr=1;colNr<=NF;colNr++) {
        if (!seen[colNr,$colNr]++) {
            val[++colRowNr[colNr],colNr] = $colNr
            numRows = (colRowNr[colNr] > numRows ? colRowNr[colNr] : numRows)
        }
    }
    numCols = (NF > numCols ? NF : numCols)
}
END {
    for (rowNr=1;rowNr<=numRows;rowNr++) {
        for (colNr=1;colNr<=numCols;colNr++) {
            printf "%s%s", val[rowNr,colNr], (colNr<numCols ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file | column -s$'\t' -t
DS571187  DS571220  DS571200  DS571194
contig1   contig3   contig4   contig7
contig2   contig4   contig6   contig8
          contig5             contig9

column的调用只是为了让对齐在站点上看起来更漂亮。

如果它不是制表符分隔的,那么为了简洁和可靠地实现这一点,你需要GNU awk for FIELDWIDTHS来识别中行中可能的空字段,比如这个输入(你应该测试其他可能的解决方案,因为我预计在你的实际数据中,后来的输入列可能比之前的列更短,这会使这个问题更难解决):

代码语言:javascript
复制
$ column -s$'\t' -t file
DS571187  DS571220  DS571200  DS571194
contig1   contig3   contig4   contig7
contig2   contig3             contig7
contig1   contig4             contig8
          contig5             contig9
                              contig9

$ awk -f tst.awk file | column -s$'\t' -t
DS571187  DS571220  DS571200  DS571194
contig1   contig3   contig4   contig7
contig2   contig4             contig8
          contig5             contig9
票数 2
EN

Stack Overflow用户

发布于 2016-08-22 23:30:36

可能需要Gawk,制表符应该是分隔符,任何一个字符分隔符都可以使用(下面的-F"\t"):

代码语言:javascript
复制
$ cat > cs.awk
NR==1 {
    nf=NF
    $1=$1
    print
}
NR>1 {
    for(i=1;i<=NF;i++)
        if($i!="")
            a[i][$i]++
}
END {
    for(i=1;i<=nf;i++)
        n[i]=asorti(a[i])
    j=asort(n)
    for(i=1;i<=n[j];i++)
        for(k=1;k<=nf;k++)
            printf "%-8s%s", a[k][i], (k<nf?OFS:ORS)
}
$ awk -F"\t" -f cs.awk cs_by_ed.txt
DS571187 DS571220 DS571200 DS571194
contig1  contig3  contig4  contig7
contig2  contig4           contig8
         contig5           contig9
票数 0
EN

Stack Overflow用户

发布于 2016-08-23 01:22:40

一种不同的方法,不一定有效,但更容易理解。最后两行用于漂亮的打印。

代码语言:javascript
复制
$ function f() { cut -d$'\t' -f$1 file1 | sed '/^$/d' | sort -u; }; 
  paste -d$'\t' <(f 1) <(f 2) <(f 3) <(f 4) | 
  sed 's/\t/ \t/g' | 
  column -ts$'\t'

DS571187   DS571220   DS571200   DS571194
contig1    contig3    contig4    contig7
contig2    contig4    contig6    contig8
           contig5               contig9
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39082214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档