列に特定の文字がある場合は、特定の列の内容を分割します。

列に特定の文字がある場合は、特定の列の内容を分割します。

このデータタブは区別されています。

ed00011   89    0.12   NA            NA                      No
ed0002s   28    0.11  c3(3.1e-1)     NA                      No
ed0001    22    0.37   NA            186_CR_NCR8_Ot(1.5e-6)  No
ed0002a   596   0.89  c301(9.5e-2)   17_CY7_Ot(0.03)         Yes

「(...)」がある場合は、これに基づいて列4と5を分割したいと思います。存在しない場合はNAのみです。たとえば、

ed00011   89   0.12  NA    NA       NA             NA          No
ed0002s   28   0.11  c3   3.1e-1    NA             NA          No
ed0001    22   0.37  NA    NA      186_CR_NCR8_Ot  1.5e-6      No
ed0002a   596  0.89 c301  9.5e-2   17_CY7_Ot       0.03        Yes

ここで提案されたコマンドを試しました。awkを使用して列を分割する しかし、「(...)」がなければ、熱が混乱します。どんな提案がありますか?

答え1

awk 'BEGIN { OFS="\t"; }
  {
        if (match($4, /\(.*\)/) > 0) {
                $4=substr($4, 1, RSTART - 1)"\t"substr($4, RSTART + 1, RLENGTH - 2)
        } else {
                $4=$4"\tNA"
        }

        if (match($5, /\(.*\)/) > 0) {
                $5=substr($5, 1, RSTART - 1)"\t"substr($5, RSTART + 1, RLENGTH - 2)
        } else {
                $5=$5"\tNA"
        }
        print
  }' input > output

ここでの基本構造は、フィールド 4 またはフィールド 5 に各行に一致する角かっこのペアが含まれていることを確認することです。その場合は、フィールドをタブ区切りの2つの値、つまり角かっこの前部分と角かっこ内の部分に置き換えます。 RSTART 値は開かれたかっこが入る位置であり、RLENGTH 値には閉じ括弧が含まれているため、長さがわずかに調整されることがわかります。フィールドに括弧がない場合は、タブ文字と「NA」が追加されます。

列が再計算されると、新しい行が印刷されます。

答え2

BEGIN {
    OFS = FS = "\t"
}

{
    # Shift some fields to the right to make space for new fields after
    # field 4 and 5.
    $8 = $6
    $6 = $5

    # Try matching "(...)" in $4
    if (match($4, "[(][^)]+[)]")) {
        # Succeeded, make $5 the bit inside the parenthesis
        $5 = substr($4, RSTART+1, RLENGTH-2)
        # ... and $4 the bit before the parenthesis.
        $4 = substr($4, 1, RSTART-1)
    } else
        $5 = "NA"

    # Repeat for $6
    if (match($6, "[(][^)]+[)]")) {
        $7 = substr($6, RSTART+1, RLENGTH-2)
        $6 = substr($6, 1, RSTART-1)
    } else
        $7 = "NA"

    print
}

テスト:

$ awk -f script.awk file
ed00011   89    0.12    NA      NA      NA      NA      No
ed0002s   28    0.11    c3      3.1e-1  NA      NA      No
ed0001    22    0.37    NA      NA      186_CR_NCR8_Ot  1.5e-6  No
ed0002a   596   0.89    c301    9.5e-2  17_CY7_Ot       0.03    Yes

フィールドは出力からタブで区切られますが、少し奇妙に見えます。渡すとうまく機能しますcolumn -tが、実際のタブは失われます。

$ awk -f script.awk file | column -t
ed00011  89   0.12  NA    NA      NA              NA      No
ed0002s  28   0.11  c3    3.1e-1  NA              NA      No
ed0001   22   0.37  NA    NA      186_CR_NCR8_Ot  1.5e-6  No
ed0002a  596  0.89  c301  9.5e-2  17_CY7_Ot       0.03    Yes

答え3

信頼できる方法

gawk '{
    for(i = 4; i < 6; i++) {
        if($i ~ /\(/) {
            split($i, arr, "[()]")
            $i = arr[1] "\t" arr[2]
        } else {
            $i = $i"\tNA"   
        }
    }
    print
}' OFS='\t' input.txt

信頼できませんが、サンプル、方法を研究しています。

sed 's/NA/&\tNA/g; s/(/\t/g; s/)//g' input.txt

このコマンドは3つの簡単なステップを実行します。

  1. s/NA/&\tNA/g- すべてタブ区切りのNAdoubleに置き換えますNA
  2. s/(/\t/g- 左角かっこをすべてタブ文字で置き換えます。
  3. s/)//g- すべての閉じ括弧を削除します。

多くの仮定をするので信頼できません。角カッコは列 4 と 5 にのみ表示でき、NA文字列は列 4 と 5 にのみ表示でき、列 4 と 5 の数値文字列は常にc3(3.1e-1)同様の形式を持ちます。したがって、このコマンドは、c3括弧で囲まれていない一意の部品しかない場合はsed機能しません。

ただし、データがサンプルと全く同じであれば、作業は完了です。

出力

ed00011 89  0.12    NA  NA  NA  NA  No
ed0002s 28  0.11    c3  3.1e-1  NA  NA  No
ed0001  22  0.37    NA  NA  186_CR_NCR8_Ot  1.5e-6  No
ed0002a 596 0.89    c301    9.5e-2  17_CY7_Ot   0.03    Yes

関連情報