我想從覆寫率報告中提取一個浮點數并將其乘以 100 以將其報告為百分比。
我可以使用sedor匹配浮點數grep,然后使用 將其相乘awk,但我想知道是否有更優雅的單一工具解決方案,可能有perl或awk只有?
該行如下所示:
<coverage line-rate="0.34869999999999995" branch-rate="0.2777" >
我目前的解決方案:
sed -n 's/^<coverage line-rate="\([0-9\.]*\)".*$/\1/p' a.txt | awk '{print (100 * $1)}'
34.87
uj5u.com熱心網友回復:
一種使用 Perl 捕獲數字并處理它(如果匹配)的方法
perl -wnE'say 100 * $1 if /^<coverage line-rate="([0-9]*\.[0-9]*)"/' file
另一種提取捕獲和處理(相乘和列印)它們的方法
perl -wnE'say 100 * $_ for /^<coverage line-rate="([0-9]*\.[0-9]*)"/' file
這使用匹配運算子 ( /.../) 的屬性在回圈提供的串列背景關系中回傳匹配項for,然后我們在回圈中處理匹配項(在這種情況下只有一個),相乘并列印。當沒有匹配時,回圈就沒有要迭代的專案。
這兩個都處理一個檔案,并且僅從匹配的行中列印結果,就像在問題中一樣。在這兩種情況下,如果需要特定的精度,則say可以替換為printf ".2f\n", $x;(兩位小數等)。
我不確定從單行中列印數字是否確實是最終需要,或者僅僅是為此目的的簡化演示,但當然還有其他方法。
還可以使用匹配項索引到串列中,以提取捕獲的模式
my $num = ( /^<coverage line-rate="([0-9]*\.[0-9]*)/ )[0];
然后在檢查后處理(是否匹配),$num *= 100 if defined $num;
如果需要更改輸入字串,就像問題中所做的那樣,也許是為了進一步的作業,達到特定的精度
# Keep four decimal places
s/^<coverage line-rate="([0-9]*\.[0-9]*).*/sprintf("%.4f", 100*$1)/e;
或者如果精度無關緊要并且可以留給口譯員
s/^<coverage line-rate="([0-9]*\.[0-9]*).*/100*$1/e;
在這兩種情況下,/e修飾符都會將替換部分作為代碼進行評估,因此我們可以在那里進行一些處理。在第一種情況下,我sprintf用來格式化替換字串,而在另一種情況下,它只是相乘。
這里可能存在一個潛在的復雜情況,即需要保留多少位數。如果它應該與原始數字相同,那么我們可能需要首先檢測有多少是
use warnings;
use strict;
use feature 'say';
# Number is shortened for demonstration
my $str = shift // q(<coverage line-rate="0.348691" branch-rate="0.2777" >);
sub process_num {
my ($num, $frac) = @_;
$num *= 100;
my $frac_len = length($frac) - 2; # keeps same digits
return sprintf "%.${frac_len}f", $num;
}
$str =~ s/^<coverage line-rate="([0-9]*\.([0-9] )).*/process_num($1, $2)/e;
say $str;
在沒有引數的情況下運行它會列印34.8691而不是原始行0.348691
因此,假設數字至少具有小數部分的數字。
uj5u.com熱心網友回復:
使用您顯示的示例,請嘗試以下awk程式。用 GNU 撰寫和測驗awk。
awk '
match($0,/coverage line-rate="([^"]*)"/,arr){
printf("%0.2f\n",arr[1] * 100)
}
' Input_file
說明:使用awk程式的match函式,在match函式中使用正則運算式coverage line-rate="([^"]*)"匹配字串coverage line-rate="直到下一次出現"并將捕獲組的值保存到陣列 arr 中。然后使用printf列印值,其中使用%0.2f\n僅獲取 2 個浮點的值。
uj5u.com熱心網友回復:
用作"欄位分隔符:
awk -F '"' '{print $2*100}' file
輸出:
34.87
uj5u.com熱心網友回復:
這是一個gnu-awk解決方案:
awk '/^<coverage /{
print 100 * gensub(/.* line-rate="([0-9.] )".*/, "\\1", "1")}' file
34.87
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425532.html
