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

标签 unix awk grep uniq

我对使用 awk/grep 等比较陌生,想过滤一些数据。我有一个大型电子表格,我想逐列显示唯一值。例如我想改变这个:

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 

看起来像这样的东西:

DS571187    DS571220    DS571200    DS571194
contig1     contig3     contig4     contig7
contig2     contig4     contig6     contig8
            contig5                 contig9     

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

琥珀色

最佳答案

假设您的输入文件看起来是用制表符分隔的:

$ 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 来识别中间行中可能为空的字段,就像这个输入(你应该测试其他潜在的解决方案,因为后面的输入列短于我预计较早的那些可能会发生在您的真实数据中,并使这个问题更难解决):

$ 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

关于unix - 使用 awk 在每列中显示唯一值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39082214/

相关文章:

linux - 将 ip 范围列表转换为 cidr

linux - 使用 bash 从文本文件中提取单词

regex - 在 Linux 文件系统上查找非 UTF8 文件名

Bash 脚本在特定范围内剪切

c - 在 ioctl 中打开的不良副作用是什么?

java - 生成外部编辑器 - 这是如何工作的?

java - 关于Java线程和进程优先级的一些问题

linux - 如何从当前文件夹中获取ino?

awk - 打印行号(如 NR),但为 $3 中的每个新字段变量重新编号

awk - 用于 UTF-16 二进制文件的 grep 和 tail -f - 尝试使用简单的 awk