将列中的短重复单词转换为数字

将列中的短重复单词转换为数字

我想将列中的短重复单词转换为数字。

在下面的示例中,我想将第 3 列中的单词更改(with ONLY 2 LETTERS)为数字,以便AA将其更改为2ABBAinto 1BBinto 0

第一列和第二列还可以包含AABBABBA这些不应该改变。

" "列由()分隔。

Id_animal Id_SNP Allele
ID01 rs01 AB
ID02 rs01 BA
ID03 rs01 AA
ID04 rs01 BB

想要的输出是:

Id_animal Id_SNP Allele
ID01 rs01 1
ID02 rs01 1
ID03 rs01 2
ID04 rs01 0

答案1

sed -i.bak -r 's/ AA$/ 2/;s/ (AB|BA)$/ 1/;s/ BB$/ 0/' input
  • -i.bak就地编辑并创建原始文件的备份input.bak
  • -r扩展正则表达式语法
  • s/ AA$/ 2/将“AA”的结束字符序列替换为 2
  • (AB|BA)AB 或 BA
  • ;分离不同的替代操作

答案2

awk

awk 'BEGIN {                                     
        t["AA"] = 2
        t["AB"] = t["BA"] = 1
        t["BB"] = 0
    }       
    $3 ~ /^[AB][AB]$/ { $3 = t[$3] }
    1' data.txt

答案3

如果您想追求您尝试的 Perl 解决方案,一种方法是使用散列作为一个简单的查找表,例如

%table = ("AA" => 2,"AB" => 1,"BA" => 1,"BB" => 0)

然后使用 的值@F[2]作为键。例如

perl -alne '
  %table = ("AA" => 2,"AB" => 1,"BA" => 1,"BB" => 0); 
  print $.==1? $_ : join " ", @F[0,1], $table{@F[2]}
' file
Id_animal Id_SNP Allele
ID01 rs01 1
ID02 rs01 1
ID03 rs01 2
ID04 rs01 0

其实虽然有一种使用 perl 来完成您描述的简单情况的方法tr- 因为它返回音译的数量。因此您可以只使用 返回值 来tr /A//计算 As 的数量:

perl -alne 'print $.==1? $_ : join " ", @F[0,1], @F[2] =~ tr/A//' file
Id_animal Id_SNP Allele
ID01 rs01 1
ID02 rs01 1
ID03 rs01 2
ID04 rs01 0

甚至更简单(使用正则表达式来识别目标字符串,而不是拆分和连接)

perl -pe 's/\b[AB]{2}\b/$& =~ tr{A}{}/ge' file


awk你可以对ie 使用同样的技巧

awk 'FNR>1 {$3 = gsub(/A/,"",$3)}1' file

相关内容