我想将列中的短重复单词转换为数字。
在下面的示例中,我想将第 3 列中的单词更改(with ONLY 2 LETTERS)
为数字,以便AA
将其更改为2
、AB
或BA
into 1
、BB
into 0
。
第一列和第二列还可以包含AA
、BB
和AB
。BA
这些不应该改变。
" "
列由()分隔。
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