awk区切り記号で列を分割する

awk区切り記号で列を分割する

ほぼここで答えを得ました。awkを区切り文字で除算し、最初の項目を取得します。 しかし、最終的な助けが必要です。ファイルがあります:

chr1    283 C       T       0.0     PASS    AF=0.730769;AO=19;DP=26;FAO=19;FDP=26;FDVR=5;FR=.;FRO=7;FSAF=12;FSAR=7;
chr1    296 A       G       0.0     PASS    AF=0.6;AO=6;DP=10;FAO=6;FDP=10;FDVR=10;FR=.;FRO=4;FSAF=3;FSAR=3;
chr1    393 CACA    ACCA    0.0     PASS    AF=0.266667,0.266667;AO=4,4;DP=16;FAO=4,4;FDP=15;FDVR=5,5;FR=.,.,.,.,HEALED,HEALED;FRO=2;FSAF=0,0;FSAR=4,4;

最後の列を「;」、「、」に分割し、個々の部分を抽出する必要があります。 AF、FSAF、FSAR項目を抽出したい。重複したアイテムがある場合は、最初のアイテムを取得します。私は以下を持っていますが、おそらくこれが最善のアプローチではないでしょう。 (そして私はこれらすべてを同じ行で行う方法を見つけることができませんでした。)

awk '{split($13,a,/;/); split(a[1],b,/,/); print b[1]}'

awk '{split($13,a,/;/); split(a[9],c,/,/); print c[1]}'

awk '{split($13,a,/;/); split(a[10],d,/,/); print d[1]}' 

ベストアンサー1

あなたの質問では完全には明確ではありませんが(下記のコメントを参照)、「二重項目が最初の項目を取る場所」と仮定すると、各行FOO=barに重複項目があることを意味します。これはあなたが望むものかもしれないと思います。 do(すべてのUnixシステムのすべてのシェルでawkを使用):

$ cat tst.awk
BEGIN { OFS=";" }
{
    delete f
    n = split($7,subFlds,/;/)
    for (i=1; i<=n; i++) {
        tag = val = subFlds[i]
        sub(/=.*/,"",tag)
        sub(/,.*/,"",val)
        if ( !(tag in f) ) {
            f[tag] = val
        }
    }
    print f["AF"], f["FSAF"], f["FSAR"]
}

$ awk -f tst.awk file
AF=0.730769;FSAF=12;FSAR=7
AF=0.6;FSAF=3;FSAR=3
AF=0.266667;FSAF=0;FSAR=4

もちろん、出力区切り記号の形式が要件OFSに合わない場合は、必要に応じて変更できます。

データにタグ=値のペアがある場合は、まず値マッピング(上記f[])のタグ配列(別名)を作成し、必要に応じてタグごとに値を印刷/テスト/変更/すべての値を印刷/テスト/変更できます。お気に入りのものを注文してください。

上記の方法は、ラベルが入力で常に同じ順序で表示されない場合や、一部の行で一部のラベルが欠落している場合にも機能します。

おすすめ記事