このデータタブは区別されています。
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つの簡単なステップを実行します。
s/NA/&\tNA/g
- すべてタブ区切りのNA
doubleに置き換えますNA
。s/(/\t/g
- 左角かっこをすべてタブ文字で置き換えます。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