从像这样的文件(分支支持在 0 到 1 之间的系统发育树):
(AJirio:0.00207,(AJama:0.00176,(AJtok:0.00034,AJkago:0.00057)0.832000:0.00080)0.934000:0.00111)0.923000
我需要获得这个(系统发育树,其中分支支持是 0 到 100 之间的整数):
(AJirio:0.00207,(AJama:0.00176,(AJtok:0.00034,AJkago:0.00057)83:0.00080)93:0.00111)92
两者之间的差异以粗体显示。有谁知道该怎么做?也许用awk?
答案1
使用 awk 使用以下命令从文件中提取所需的内容(temp.txt
是输入文件):
awk -F ")" '{print $1 ")" substr($2,3,2) substr($2,9) ")" substr($3,3,2) substr($3,9) ")" substr($4,3,2) }' temp.txt
答案2
sed
如果所有数据看起来都像样本数据,那么这对于 来说相当容易:
sed -e 's/)0\.0\(.\)[0-9]*/)\1/g' -e 's/)0\.\(..\)[0-9]*/)\1/g' -e 's/)1\.00[0-9]*/)100/g' file
它具有三个-e
子命令,它们是同一主题的变体。每个都查找 a)
后跟 0.00 到 1.00 之间的小数,至少有两位小数,并将其替换为 a)
后跟 0 到 100 之间的相应整数。每个 都以 结尾以g
使其成为全局变量,因此它会影响任何每条线上的分支支撑数。不幸的是,这会截断数字而不是四舍五入,因此0.838
变为83
而不是84
。
细节:
s/)0\.0\(.\)[0-9]*/)\1/g
0.0
查找以(例如0.00
or ) 开头的数字,0.07
并将其替换为第二个小数位,因此0.00
and0.07
变为0
and7
而不是00
and07
。[0-9]*
匹配第二个数字之后的任意数量的数字并丢弃它们(通过将它们替换为空)。s/)0\.\(..\)[0-9]*/)\1/g
这是一般情况:0.
后面跟着不是0
.这将更改为0.832000
等83
。s/)1\.00[0-9]*/)100/g
这会查找1.00
并将其更改为100
.如果您确定这永远不会出现在您的数据中,则可以省略此子命令。
如果,正如您在问题标题中所建议的那样,您还希望能够在每个子命令中将0,234000
(用逗号作为小数点)更改为23
, 更改\.
为。[,.]
答案3
$ cat test.txt
(AJirio:0.00207,(AJama:0.00176,(AJtok:0.00034,AJkago:0.00057)0.832000:0.00080)0.934000:0.00111)0.923000
$ awk -F\) '{for(i=NF-2;i<=NF;i++){split($i,arr,":");$i=sprintf("%2d:%s",arr[1]*100,arr[2])}}1' OFS=\) test.txt | sed "s/:$//"
(AJirio:0.00207,(AJama:0.00176,(AJtok:0.00034,AJkago:0.00057)83:0.00080)93:0.00111)92