添加两个带有字母的字段,这些字母在字段 4 和 5 中编码为以冒号分隔的数字

添加两个带有字母的字段,这些字母在字段 4 和 5 中编码为以冒号分隔的数字

我想创建第 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)推断数组$",然后打印它。

假设:

  1. 没有前导 TAB,这会破坏数组中字段的计数@F
  2. 第四个和第五个字段被假定为one-hot,这意味着,总是有一个非零数字肯定存在。
  3. 第四和第五字段没有任何以 0 开头的非零数字。
  4. 第四和第五字段没有全00作为零。
  5. 第四和第五字段正好有六个数字,由单个冒号分隔,并且没有尾随/前导冒号。

相关内容