2017-03-01 120 views
0

我試圖實現下面的FAKE代碼所示的功能:計算淨減速率並更新淨日誌。 可能有人向我展示正確的代碼?謝謝。如何將linux shell變量寫入文件的給定行?

#!/bin/bash 
    #check_net.sh 

    net_link_error_total=33 
    net_link_ok_total=55 
    save_link_rate() 
    { 
     sed -i '1 cnet_link_error_total=$net_link_error_total' yy.log 
     sed -i '2 cnet_link_ok_total=$net_link_ok_total' yy.log 

     net_link_ok_rate=net_link_ok_total/(net_link_ok_total+net_link_error_total) * 100% 
     sed -e "3c net_link_ok_rate= /$net_link_ok_rate" yy.log  
    } 

    save_link_rate 

我執行sed -i '2 cnet_link_ok_total=$net_link_ok_total' yy.log

  • 後yy.log是net_link_error_total=$net_link_error_total

  • ,但我想它是net_link_error_total=33

回答

1

在前兩個sed命令中,變量不會在單引號內擴展。

將最後一個命令應用於第三行將按預期工作,但將擴展限制爲僅變量並且不要將整個sed命令括在雙引號內是一種好習慣。而且我會爲每可讀性sed的c命令後加上一個空格:

sed -i '1c net_link_error_total='"$net_link_error_total"'' yy.log 
sed -i '2c net_link_ok_total='"$net_link_ok_total"'' yy.log 

sed -e '3c net_link_ok_rate= /'"$net_link_ok_rate"'' yy.log 

而且你的速度計算是錯誤的。您可以使用bc此:

net_link_ok_rate=$(echo "scale=2; $net_link_ok_total/($net_link_ok_total+$net_link_error_total) * 100" | bc) 

最後請注意,你的最後一個sed命令的文件將不到位的進行編輯,因爲-i標誌丟失。

+0

行'net_link_ok_rate = net_link_ok_total /(net_link_ok_total + net_link_error_total )* 100% '不應該工作正確嗎?它不是在算術語境中完成的,不是嗎?或者我在這裏錯過了什麼? – Inian

+0

前兩行看起來不錯。 –

+0

@BeyondOcean前兩行?如果你的意思是前兩個sed命令,它們不是。這就是爲什麼你沒有看到預期的替代品。 – SLePort

0

使用雙引號而不是單引號,因爲單引號會限制變量的替換。在你的情況,你想要的是:

sed -i "1 cnet_link_error_total=$net_link_error_total" yy.log 
sed -i "2 cnet_link_ok_total=$net_link_ok_total" yy.log 

如果你想要做一個浮動師bash,你應該使用的工具如bc。在你的情況,例如:

ok_rate=$(echo "scale=2; $ok_total/$((ok_total+error_total))" | bc) 
0

如果你有GNU AWK與就地模塊(4.1.0及以上版本),則:

awk -i inplace -v error=$net_link_error_total -v ok=$net_link_ok_total \ 
    'NR == 1 {$0 = "net_link_error_total=" error} 
    NR == 2 {$0 = "net_link_ok_total=" ok} 
    NR == 3 {$0 = "net_link_ok_rate=" (ok + error)*100/ok} 
    1' yy.log 

$0是當前行, NR的行號,所以我將每個匹配行設置爲所需的字符串。

如果字段名都已經在這些文件中的行,你可以進一步簡化,但設置字段,而不是整條生產線的:

awk -i inplace -F= -v error=$net_link_error_total -v ok=$net_link_ok_total \ 
    'NR == 1 {$2 = error} 
    NR == 2 {$2 = ok} 
    NR == 3 {$2 = (ok + error)*100/ok} 
    1' yy.log