Extraia colunas de substrings de cabeçalho correspondentes a arquivos de texto

Extraia colunas de substrings de cabeçalho correspondentes a arquivos de texto

Gostaria de extrair colunas delimitadas por tabulações de um arquivo de texto "columns.txt" no qual o cabeçalho (primeira linha) corresponde às substrings listadas em outro arquivo de texto "strings".
"colunas.txt" tem esta aparência:

A   B   C   D   E   F   rs243_A   rs546_G   rs987_T   rs025_C   ...
A   B   C   D   E   F   0         0         0         1         ...
A   B   C   D   E   F   1         1         2         2         ...
A   B   C   D   E   F   0         1         2         0         ...
... ... ... ... ... ... ...       ...       ...       ...       ...

"strings.txt" fica assim:

rs243
rs987  
...

O arquivo de texto de saída deve copiar as colunas 1 a 6 de "columns.txt" e, em seguida, adicionar todas as colunas extraídas (delimitadas por tabulação) especificadas em "strings.txt". O arquivo de saída "output.txt" deve ficar assim:

A   B   C   D   E   F   rs243   rs987   ...
A   B   C   D   E   F   0       0       ...
A   B   C   D   E   F   1       2       ...
A   B   C   D   E   F   0       2       ...
... ... ... ... ... ... ...     ...     ...

O código que estou usando imprime as colunas 1 a 6 em "output.txt" como desejo, mas não adiciona as colunas extraídas:

awk -F '\t' -f /data/p_00614/ABCD/scripts/extract.awk /data/strings.txt /data/columns.txt > /data/output.txt

com "extract.awk":

BEGIN { OFS = FS }

FNR == NR {
    sub("_.*", "", $1)
    columns[$1] = 1
    next
}

FNR == 1 {
    for (i = 1; i <= NF; ++i)
        if (i <= 6 || $i in columns)
            keep[i] = 1
}

{
    nf = split($0, fields, FS)
    $0 = ""
    j = 0

    for (i = 1; i <= nf; ++i)
        if (i in keep)
            $(++j) = fields[i]

    print 
}

eu penso isso

sub("_.*", "", $1)

não funciona. "_.*"provavelmente não corta todas as substrings, _mas apenas correspondências exatas. Alguma sugestão sobre como consertar isto? Obrigado!

Responder1

Este é um bug no código que forneci emuma resposta anterior a uma de suas perguntas(agora corrigido). O _.*bit não deve ser removido das strings que estão sendo lidas strings.txt, mas sim dos dados que estão sendo lidos columns.txt.

Roteiro corrigido:

BEGIN { OFS = FS }

FNR == NR {
    columns[$1] = 1
    next
}

FNR == 1 {
    for (i = 1; i <= NF; ++i) {
        sub("_.*", "", $i)
        if (i <= 6 || $i in columns)
            keep[i] = 1
    }
}

{
    nf = split($0, fields, FS)
    $0 = ""
    j = 0

    for (i = 1; i <= nf; ++i)
        if (i in keep)
            $(++j) = fields[i]

    print 
}

Observe as pequenas alterações nos blocos FNR == NRe FNR == 1do que você tem na pergunta.

informação relacionada