将两个不同模式之间的数字相乘并打印整个文件

web*_*web 2 sed awk arithmetic

我想用相乘的数字替换模式之间的数字并打印所有行。该文件是 newick 格式的树文件,仅包含一行。我的目标是之后)和之前的所有数字:。我想将两个符号之间的所有数字乘以 100。

文件:

((((A_8:0.000846,(A_5:0.002449,(A_1:1e-06,((A_4:1e-06,((A_7:1e-06,A_6:0.001061)0.714000:1e-06,A_3:1e-06)0.314500:1e-06)0.358667:1e-06,A_2:1e-06)0.361000:1e-06)0.434800:1e-06)0.683500:0.001619)0.888571:0.001931,A_9:0.00069)0.688471:0.000691,...
Run Code Online (Sandbox Code Playgroud)

对我来说,最简单的方法似乎是通过先用新行替换所有“:”符号来拆分文件。所以我所有的目标数字现在都在单独的行中并出现在). 然后,我使用下面的 awk 脚本将目标数字乘以 100,但没有设法保留没有目标数字的行。

脚本:

((((A_8:0.000846,(A_5:0.002449,(A_1:1e-06,((A_4:1e-06,((A_7:1e-06,A_6:0.001061)0.714000:1e-06,A_3:1e-06)0.314500:1e-06)0.358667:1e-06,A_2:1e-06)0.361000:1e-06)0.434800:1e-06)0.683500:0.001619)0.888571:0.001931,A_9:0.00069)0.688471:0.000691,...
Run Code Online (Sandbox Code Playgroud)

)在这种情况下,如何将数字相乘并打印整个文件?或者还有其他更简单的方法可以直接查找:和之间的数字),将它们乘以 100 并打印整个文件?

更新:预期输出

((((A_8:0.000846,(A_5:0.002449,(A_1:1e-06,((A_4:1e-06,((A_7:1e-06,A_6:0.001061)71.4000:1e-06,A_3:1e-06)31.4500:1e-06)35.8667:1e-06,A_2:1e-06)36.1000:1e-06)43.4800:1e-06)68.3500:0.001619)88.8571:0.001931,A_9:0.00069)68.8471:0.000691,...)
Run Code Online (Sandbox Code Playgroud)

nez*_*dka 6

awk 'BEGIN {OFS=FS=":"; ORS=RS=")"} NR>1 {$1=sprintf("%.4f", $1 * 100)}1' df9.tree
Run Code Online (Sandbox Code Playgroud)

如果您接受分隔 RS 记录和 FS 字段,则所需编号将始终位于第一条记录之后的第一个字段中。

  • 尝试在 `-F:` 后立即添加一个空格和 `-v OFS=:`。这会将输出字段分隔符 (OFS) 设置为 `:`,与输入字段分隔符 (FS) 相同。 (2认同)

cas*_*cas 5

$ perl -pe 's/\)([-0-9.]+):/sprintf ")%.4f:", $1 * 100/eg' df9.tree
((((A_8:0.000846,(A_5:0.002449,(A_1:1e-06,((A:1e-06,((A_7:1e-06,A:0.001061)71.4000:1e-06,A:1e-06)31.4500:1e-06)35.8667:1e-06,A:1e-06)36.1000:1e-06)43.4800:1e-06)68.3500:0.001619)88.8571:0.001931,A:0.00069)68.8471:0.000691,...
Run Code Online (Sandbox Code Playgroud)

替换紧跟在一个)字符之后并:以数字乘以 100的字符结尾的所有数字(定义为一个或多个数字、句点或减号字符的序列)。

例如)0.714000:被更改为)71.4000:

它使用 perl 的/e正则表达式评估修饰符在s///运算符的 RHS 中执行 perl 代码。查看man perlop和搜索s\/PATTERN详细信息。sprintf用于将数字格式化为具有 4 个小数位。


如果之间的数量):形式上可以是普通的十进制表示(“0.714000”)或“C漂浮”式的科学记数法(“1E-06”),正则表达式需要只是一点点变得更复杂,以匹配所有可能的变化:

$ perl -pe 's/\)(([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?):/sprintf ")%.4f:", $1 * 100/eg' df9.tree
((((A_8:0.000846,(A_5:0.002449,(A_1:1e-06,((A_4:1e-06,((A_7:1e-06,A_6:0.001061)71.4000:1e-06,A_3:1e-06)31.4500:1e-06)35.8667:1e-06,A_2:1e-06)36.1000:1e-06)43.4800:1e-06)68.3500:0.001619)88.8571:0.001931,A_9:0.00069)68.8471:0.000691,...)
Run Code Online (Sandbox Code Playgroud)

以下也可能有效,但可能有些数字不匹配:

perl -pe 's/\)([-0-9.eE+]+):/sprintf ")%.4f:", $1 * 100/eg'
Run Code Online (Sandbox Code Playgroud)