ヘッダー部分文字列に一致するテキストファイルから列を抽出する

ヘッダー部分文字列に一致するテキストファイルから列を抽出する

ヘッダー (最初の行) が別のテキスト ファイル "strings" にリストされているサブ文字列と一致するテキスト ファイル "columns.txt" からタブ区切りの列を抽出したいと思います。
"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  
...

出力テキスト ファイルでは、「columns.txt」から列 1 ~ 6 をコピーし、「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

関連情報