如何解析空格分隔的文本文件

如何解析空格分隔的文本文件

我有一个这样的文本文件:

Fam1000: CMIN|CMIN_9-RA CMIN|ABC_7-RA GCLA|EFX5.1 GCUC|GCUC_7-RA
Fam1001: GCLA|EFX6.1 GCLA|EFX7.1
Fam1002: GCLA|EFX5.1 GCLA|EFX2.1 GCUC|GCUC_8-RA GCUC|GCUC_8-RA
Fam1003: CMIN|CMIN_001265-RA CMIN|CMIN_007282-RA

在这个文件中,每行包含多个值(以空格分隔)。每个值在管道符号前都有一个特定的组标识符(例如 CMIN|CMIN_9-RA 和 CMIN|ABC_7-RA 属于 CMIN 组)。管道后面的字母可以是任意随机字母和数字。

知道文件中组标识符的总数和名称(在本例中我有 3 个:分别是 CMIN、GCLA 和 GCUC)。现在我想将此文件解析为一个文件,该文件显示每行每个组的值数量。最后,我希望得到这样的输出(可以用空格或制表符分隔):

            CMIN    GCLA    GCUC
Fam1000:    2       1       1
Fam1001:    0       2       0
Fam1002:    0       2       2
Fam1003:    2       0       0

我认为我应该首先删除每个值的 | 后面的所有元素,然后计算每行的唯一标识符的数量,但我不知道如何使用 awk 执行此操作。有人可以帮忙吗?

此外,这只是一个简化的例子,实际文件相当大,有几千行和几十个组。

谢谢。

答案1

虽然不是最漂亮的解决方案,但它确实有效。此脚本已在 Linux Ubuntu 上测试过。它可能无法在 Mac 上运行,因为我使用的是gawk

您需要将以下代码保存在文件中,例如parsetext.sh

运行此命令以启用执行:

chmod +x parsetext.sh

然后使用你的 inputfile.txt 运行它:

./parsetext.sh inputfile.txt

以下是完成该作业的脚本:

#!/bin/bash
sed -e 's/|[^ ]\+//g; s/://' "$1"|\
gawk '{

        for ( i = 2; i <= NF; i++) {
        rows[$1][$i]++
        keys[$i]++
    } 
    } 
END {
    n = asorti(keys, tmp)
    printf("\t")
    for ( i=1; i<= n; i++) { printf("%s\t", tmp[i]) }
    printf("\n")
    for ( r in rows ) { 
        printf("%s\t", r)
        for (i=1; i<= n; i++) {
            value = 0
            k = tmp[i]
            if (rows[r][k] > 0) value = rows[r][k] 
            printf("%s\t", value)
        }
        printf("\n")
    }

}'

示例输出:

    CMIN    GCLA    GCUC    
Fam1000 2   1   1   
Fam1001 0   2   0   
Fam1002 0   2   2   
Fam1003 2   0   0   

相关内容