将这种形式的数字:0.873000 / 0,234000 更改为这种形式:87 / 23

将这种形式的数字:0.873000 / 0,234000 更改为这种形式:87 / 23

从像这样的文件(分支支持在 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.00or ) 开头的数字,0.07并将其替换为第二个小数位,因此0.00and0.07变为0and7而不是00and 07。  [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

相关内容