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

Ama*_*nga 4 terminal text-processing

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

在下面的例子中,我想改变的话(with ONLY 2 LETTERS)在数字柱3,以使得AA被改变为2ABBA1BB0

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

列由" "()分隔。

Id_animal Id_SNP Allele
ID01 rs01 AB
ID02 rs01 BA
ID03 rs01 AA
ID04 rs01 BB
Run Code Online (Sandbox Code Playgroud)

想要的输出是:

Id_animal Id_SNP Allele
ID01 rs01 1
ID02 rs01 1
ID03 rs01 2
ID04 rs01 0
Run Code Online (Sandbox Code Playgroud)

Sat*_*ura 6

awk

awk 'BEGIN {                                     
        t["AA"] = 2
        t["AB"] = t["BA"] = 1
        t["BB"] = 0
    }       
    $3 ~ /^[AB][AB]$/ { $3 = t[$3] }
    1' data.txt
Run Code Online (Sandbox Code Playgroud)

  • 查找表是一个有趣的想法。我正在设计一个更加华丽的 awk 解决方案(我实际上是在让 awk 计算 A 的数量),但我更喜欢这个。我可能会推荐匹配一行的第三个字段,而不是匹配非第一行:``$3 ~ /^[AB][AB]$/ ...`` (2认同)

Sun*_*eep 6

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


ste*_*ver 5

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

%table = ("AA" => 2,"AB" => 1,"BA" => 1,"BB" => 0)
Run Code Online (Sandbox Code Playgroud)

然后使用的值@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
Run Code Online (Sandbox Code Playgroud)

其实虽然有一种方法,你用perl的描述的简单情况tr-因为它返回transliterations.Hence的数量,您可以只使用的返回值tr /A//来计算作为数量:

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
Run Code Online (Sandbox Code Playgroud)

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

perl -pe 's/\b[AB]{2}\b/$& =~ tr{A}{}/ge' file
Run Code Online (Sandbox Code Playgroud)


你可以对awkie使用同样的技巧

awk 'FNR>1 {$3 = gsub(/A/,"",$3)}1' file
Run Code Online (Sandbox Code Playgroud)