1

У меня есть текстовый файл, как это:

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 ответ1

2

Не самое красивое решение, но оно работает. Этот скрипт был протестирован на 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   

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .