Как отсортировать строки файла в виде матрицы?

Я хотел бы знать, как я могу отсортировать строки файла следующим образом:

Мой файл - file.txt (с разделителями табуляцией):

g1 00A98_01563 00554_01552 CCUG38_01373 
g2 00554_01444
g3 00A98_04566 CCUG38_05322

Я хочу получить это (с разделителями табуляцией):

g 00A98 00554 CCUG38
g1 1 1 1
g2 0 1 0
g3 1 0 1

И / или также в этом формате (с разделителями табуляции):

g 00A98 00554 CCUG38
g1 00A98_01563 00554_01552 CCUG38_01373 
g2             00554_01444 
g3 00A98_04566             CCUG38_05322

Как я могу сделать это с помощью командная строка с помощью sort, awk, grep или другого?

Всего наилучшего, С уважением

-2
задан 2 July 2021 в 18:55

2 ответа

Это toMatrix.awk

#!/usr/bin/env gawk -f
BEGIN { FS = OFS = "\t" }

{
    for (i=2; i<=NF; i++) {
        x=$i
        sub(/_.*/, "", x)
        if (!(x in values)) {
            values[x] = 1
            ordered[++value] = x
        }
        g[NR] = $1
        data[NR][x]=1
    }
}

END {
    printf "%s", "g"
    for (i = 1; i <= value; i++)
        printf "%s%s", OFS, ordered[i]
    print ""

    for (nr = 1; nr <= NR; nr++) {
        printf "%s", g[nr]
        for (i = 1; i <= value; i++)
            printf "%s%s", OFS, 0 + data[nr][ordered[i]]
        print ""
    }
}
$ gawk -f toMatrix.awk file.txt
g   00A98   00554   CCUG38
g1  1   1   1
g2  0   1   0
g3  1   0   1
2
ответ дан 28 July 2021 в 11:22

Используя Miller , обработайте ввод как пары ключ-значение с разделителями, используя TAB в качестве разделителя входных полей и подчеркивание в качестве разделителя входных пар, и установите для вывода значение TSV. Затем вы можете разобрать свои данные

$ mlr --idkvp --ifs tab --ips '_' --otsv unsparsify file.txt
1       00A98   00554   CCUG38
g1      01563   01552   01373
g2              01444
g3      04566           05322

Затем вы можете добавить различные преобразования, например.

$ mlr --idkvp --ifs tab --ips '_' --otsv unsparsify --fill-with 0 then put '
    for(k,v in mapexcept($*,"1")){if(v != 0){$[k] = 1}}
  ' then rename "1","g" file.txt
g       00A98   00554   CCUG38
g1      1       1       1
g2      0       1       0
g3      1       0       1

или

$ mlr --idkvp --ifs tab --ips '_' --otsv unsparsify then put -S '
    for(k,v in mapexcept($*,"1")){if(v != ""){$[k] = k ."_". v}}
  ' then rename "1","g" file.txt
g       00A98   00554   CCUG38
g1      00A98_01563     00554_01552     CCUG38_01373
g2              00554_01444
g3      00A98_04566             CCUG38_05322

В последнем случае выравнивание выглядит «выключенным», но вывод с - ocsv вместо - tsv должен подтвердить, что это правильно.

4
ответ дан 28 July 2021 в 11:22

Другие вопросы по тегам:

Похожие вопросы: