我想创建第 8 和第 9 字段/列,并在第 4 和 5 列中将适当的字母编码为数字。六个冒号分隔的数字对应于A:T:C:G:N:del
注意:第 6 列和第 7 列中的某些行是空的,我通过插入 NA 来修复此问题:
awk -F'[[:space:]]' '$5 && !$6{ $6="NA" }1'
awk -F'[[:space:]]' '$6 && !$7{ $7="NA" }1'
然后再次使用制表符分隔文件sed -e 's/ /\t/g'
文件.tsv
NW_006532398.1 302035 C 0:0:32:0:0:0 42:0:0:0:0:0 KCND2 intergenic_region
NW_006532656.1 289636 C 0:0:28:0:0:0 0:28:0:0:0:0 CNTN1 intron_variant
NW_006532762.1 6396 C 0:54:0:0:0:0 0:0:53:0:0:0 NA intergenic_region
NW_006532762.1 25741 C 0:0:62:0:0:0 0:43:0:0:0:0 NA intergenic_region
NW_006532762.1 32304 T 0:60:0:0:0:0 0:0:49:0:0:0 NA intergenic_region
NW_006532762.1 179065 G 0:0:0:45:0:0 59:0:0:0:0:0 DOCK4 intron_variant
输出示例.tsv
NW_006532398.1 302035 C 0:0:32:0:0:0 42:0:0:0:0:0 KCND2 intergenic_region C A
NW_006532656.1 289636 C 0:0:28:0:0:0 0:28:0:0:0:0 CNTN1 intron_variant C T
NW_006532762.1 6396 C 0:54:0:0:0:0 0:0:53:0:0:0 NA intergenic_region T C
NW_006532762.1 25741 C 0:0:62:0:0:0 0:43:0:0:0:0 NA intergenic_region C T
NW_006532762.1 32304 T 0:60:0:0:0:0 0:0:49:0:0:0 NA intergenic_region T C
NW_006532762.1 179065 G 0:0:0:45:0:0 59:0:0:0:0:0 DOCK4 intron_variant G A
任何帮助是极大的赞赏!!
答案1
$ cat tst.awk
BEGIN {
FS=OFS="\t"
split("A:T:C:G:N:del",map,/:/)
}
{ print $0, vals2id($4), vals2id($5) }
function vals2id(vals, arr, i, id) {
split(vals,arr,/:/)
for (i in arr) {
if (arr[i] != 0) {
id = map[i]
}
}
return id
}
$ awk -f tst.awk file
NW_006532398.1 302035 C 0:0:32:0:0:0 42:0:0:0:0:0 KCND2 intergenic_region C A
NW_006532656.1 289636 C 0:0:28:0:0:0 0:28:0:0:0:0 CNTN1 intron_variant C T
NW_006532762.1 6396 C 0:54:0:0:0:0 0:0:53:0:0:0 NA intergenic_region T C
NW_006532762.1 25741 C 0:0:62:0:0:0 0:43:0:0:0:0 NA intergenic_region C T
NW_006532762.1 32304 T 0:60:0:0:0:0 0:0:49:0:0:0 NA intergenic_region T C
NW_006532762.1 179065 G 0:0:0:45:0:0 59:0:0:0:0:0 DOCK4 intron_variant G A
答案2
我相信下面的 sed 脚本会做你想做的事情:
s/\t[1-9][0-9]*:0:0:0:0:[^\t]*\t/&A\t/g
s/\t0:[1-9][0-9]*:0:0:0:[^\t]*\t/&T\t/g
s/\t0:0:[1-9][0-9]*:0:0:[^\t]*\t/&C\t/g
s/\t0:0:0:[1-9][0-9]*:0:[^\t]*\t/&G\t/g
s/\t0:0:0:0:[1-9][0-9]*:[^\t]*\t/&N\t/g
s/\t0:0:0:0:0:[1-9][0-9]*\t/&del\t/g
s/^\t(([^\t]*\t){4})([^\t]*)\t([^\t]*)(\t[^\t]*)(\t.*)/\1\4\6\t\3\5/
运行:
sed -rf script.sed file.tsv > output.tsv
答案3
我们可以使用 Perl 和 sed 实用程序执行以下操作:
perl -F'\t' -pale '$"="\t";
/(?:^|:)(?=[1-9])/g, push(@F, qw[A T C G N del][+pos>>1]) for @F[3,4];
$_="@F";
' file.tsv
NW_006532398.1 302035 C 0:0:32:0:0:0 42:0:0:0:0:0 KCND2 intergenic_region C A
NW_006532398.1 302035 C 0:0:0:0:0:2 42:0:0:0:0:0 KCND2 intergenic_region del A
NW_006532656.1 289636 C 0:0:28:0:0:0 0:28:0:0:0:0 CNTN1 intron_variant C T
NW_006532762.1 6396 C 0:54:0:0:0:0 0:0:53:0:0:0 NA intergenic_region T C
NW_006532762.1 25741 C 0:0:62:0:0:0 0:43:0:0:0:0 NA intergenic_region C T
NW_006532762.1 32304 T 0:60:0:0:0:0 0:0:49:0:0:0 NA intergenic_region T C
NW_006532762.1 179065 G 0:0:0:45:0:0 59:0:0:0:0:0 DOCK4 intron_variant G A
sed -re '
1{x;s/.*/A:T:C:G:N:del/;x;}
s/\t/&\n/3;G;ba
:b;s/\t/&\n/4;G
:a;s/\n0:(.*)\n[^:]+:/0:\n\1\n/;ta
s/\n//;s/\n([^:]+)/\t\1\n/;s/\n.*//;s/^//;tc
:c;s/\t/&/8;t;bb
' file.tsv
说明:
在当前记录的第四
$F[3]
和第五字段(又名行)上,我们$F[4]
$_
确定第一个非零数字的位置(在该字段内)。凭借事实
占用
0:
2 个位置,我们将找到的位置减半以获得qw[A T C G N del]
该字段的匿名数组索引。现在只需将找到的 A/T/C/G/N 或 del 添加到 array 即可
@F
。@F
然后我们使用(tab)推断数组$"
,然后打印它。
假设:
- 没有前导 TAB,这会破坏数组中字段的计数
@F
。 - 第四个和第五个字段被假定为
one-hot
,这意味着,总是有一个非零数字肯定存在。 - 第四和第五字段没有任何以 0 开头的非零数字。
- 第四和第五字段没有全00作为零。
- 第四和第五字段正好有六个数字,由单个冒号分隔,并且没有尾随/前导冒号。