在字符串的第二/第三/第四次出现时添加字母?

时间:2017-12-12 14:15:36

标签: shell unix awk sed

我有一个大文本文件,如下所示:

1   1:49298 0   49298   T   C
1   1:54676 0   54676   T   C
1   1:54676 0   54676   A   G
1   1:86028 0   86028   C   T
1   1:86028 0   86028   T   G
1   1:86028 0   86028   A   G
1   1:91536 0   91536   T   G

第二列包含一些倍数 - 肯定是重复的,有可能有三次等,但我还没有完全探索过。

我想将字母'b'添加到第2列中第二次出现的末尾,将'c'添加到第三次出现,将'd'添加到第四次出现,依此类推。所以输出文件应如下所示:

1   1:49298 0   49298   T   C
1   1:54676 0   54676   T   C
1   1:54676b    0   54676   A   G
1   1:86028 0   86028   C   T
1   1:86028b    0   86028   T   G
1   1:86028c    0   86028   A   G
1   1:91536 0   91536   T   G

我认为这可以使用awk完成,但我还没有想出任何可行的选项。

4 个答案:

答案 0 :(得分:3)

这可能是你正在寻找的东西:

$ awk 'cnt[$2]++ { $2=sprintf("%s%c", $2, 96 + cnt[$2]) } 1' file | column -t
1  1:49298   0  49298  T  C
1  1:54676   0  54676  T  C
1  1:54676b  0  54676  A  G
1  1:86028   0  86028  C  T
1  1:86028b  0  86028  T  G
1  1:86028c  0  86028  A  G
1  1:91536   0  91536  T  G

答案 1 :(得分:2)

另一个awk,可让您控制附加的代码

$ awk -v codes="$(echo {b..z})" 'BEGIN{split(codes,s)} 
                                      {$2=$2 s[c[$2]++]}1' file | column -t

1  1:49298   0  49298  T  C
1  1:54676   0  54676  T  C
1  1:54676b  0  54676  A  G
1  1:86028   0  86028  C  T
1  1:86028b  0  86028  T  G
1  1:86028c  0  86028  A  G
1  1:91536   0  91536  T  G

答案 2 :(得分:1)

或perl:

perl -lane '
    $F[1] .= chr(96 + $count{$F[1]}) if $count{$F[1]}++ > 0;
    print join "\t", @F
' file

答案 3 :(得分:-1)

还有这个:

awk '{if ($4 == previous) {i++; print $1, $2sprintf("%c", 97+ i),$3,$4,$5,$6} else {previous = $4; i = 0; print;}}' file
1   1:49298 0   49298   T   C
1   1:54676 0   54676   T   C
1 1:54676b 0 54676 A G
1   1:86028 0   86028   C   T
1 1:86028b 0 86028 T G
1 1:86028c 0 86028 A G
1   1:91536 0   91536   T   G