Awk
將兩個不同模式之間的數字相乘並列印整個文件
我想用相乘的數字替換模式之間的數字並列印所有行。該文件是 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,...
對我來說,最簡單的方法似乎是通過首先用新行替換所有“:”符號來拆分文件。所以我所有的目標數字現在都在單獨的行中,並出現在
)
. 然後,我使用下面的 awk 腳本將目標數字乘以 100,但沒有設法保留沒有目標數字的行。腳本:
sed 's/:/\n/g' df9.tree | awk -F")" '{OFS=")"} $2=$2*100 {print $0}' sed 's/:/\n/g' df9.tree | awk '$NF ~/)/ {$NF *=100}1'
在這種情況下,如何將數字相乘
)
並列印整個文件?還是有其他更簡單的方法可以直接查找介於:
and之間的數字)
,將它們乘以 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,...)
$ 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,...
替換緊跟一個
)
字元並:
以數字乘以 100 的字元結尾的所有數字(定義為一個或多個數字、句點或減號的序列)。例如
)0.714000:
更改為)71.4000:
它使用 perl 的
/e
正則表達式求值修飾符在運算符的 RHS 中執行 perl 程式碼s///
。查看man perlop
並蒐索s\/PATTERN
詳細資訊。sprintf
用於將數字格式化為小數點後 4 位。如果和之間的數字
)
可以:
是簡單的十進製表示法(“0.714000”)或“C float”風格的科學記數法(“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,...)
以下也可能有效,但可能有一些數字不匹配:
perl -pe 's/\)([-0-9.eE+]+):/sprintf ")%.4f:", $1 * 100/eg'
awk 'BEGIN {OFS=FS=":"; ORS=RS=")"} NR>1 {$1=sprintf("%.4f", $1 * 100)}1' df9.tree
如果您接受將 RS 記錄和 FS 欄位分開,則所需的編號將始終位於第一條記錄之後的第一個欄位中。