Извлечь столбцы из текстового файла, соответствующие подстрокам заголовка

Извлечь столбцы из текстового файла, соответствующие подстрокам заголовка

Я хотел бы извлечь столбцы, разделенные табуляцией, из текстового файла "columns.txt", в котором заголовок (первая строка) соответствует подстрокам, перечисленным в другом текстовом файле "strings".
"columns.txt" выглядит следующим образом:

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» выглядит так:

rs243
rs987  
...

Выходной текстовый файл должен копировать столбцы 1-6 из "columns.txt", а затем добавлять все извлеченные столбцы (разделенные табуляцией), указанные в "strings.txt". Выходной файл "output.txt" должен выглядеть следующим образом:

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       ...
... ... ... ... ... ... ...     ...     ...

Код, который я использую, выводит столбцы 1-6 в «output.txt» так, как мне нужно, но не добавляет извлеченные столбцы:

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

с "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 
}

я думаю что

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

не работает. "_.*"вероятно, не вырезает каждую подстроку, начиная с, _а только точные совпадения. Есть предложения, как это исправить? Спасибо!

решение1

Это ошибка в коде, который я привел вболее ранний ответ на один из ваших вопросов(теперь исправлено). _.*Бит следует удалять не из строк, считываемых из strings.txt, а из данных, считываемых из columns.txt.

Исправленный сценарий:

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 
}

Обратите внимание на совсем небольшие изменения в блоках FNR == NRи FNR == 1по сравнению с тем, что вы указали в вопросе.

Связанный контент