如何将linux shell变量写入文件的给定行?

时间:2017-03-01 07:00:12

标签: bash shell

我尝试实现如下FAKE代码所示的功能:计算净减速率并更新净日志。 可能有人给我看正确的代码?感谢。

    #!/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

3 个答案:

答案 0 :(得分: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标志。

答案 1 :(得分: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)

答案 2 :(得分:0)

如果你有内置模块(版本4.1.0及更高版本)的GNU awk,那么:

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