Reputation: 45
I tried to Realize the function shown as the below FAKE code: to compute the net down rate and update the net log. May somebody show me the right code? Thanks.
#!/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
After I executed sed -i '2 cnet_link_ok_total=$net_link_ok_total' yy.log
The yy.log is net_link_error_total=$net_link_error_total
BUT I want it to be net_link_error_total=33
.
Upvotes: 0
Views: 72
Reputation: 4887
If you have GNU awk with the in-place module (versions 4.1.0 and above), then:
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
is the current line, and NR
the line number, so I set each matching line to the required string.
If the field names are already in the file in those lines, you can simplify it further, but setting the field instead of the whole line:
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
Upvotes: 0
Reputation: 15461
In the first two sed commands, variables are not expanded within single quotes.
Your last command applied to third line will works as intended but it's a good practice to restrict expansion to only variables, and not to enclose whole sed command within double quotes. Moreover I would add a space after each sed c
commands for readability:
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
Also your rate calculation is wrong. You can use bc
for this:
net_link_ok_rate=$( echo "scale=2; $net_link_ok_total/($net_link_ok_total+$net_link_error_total) * 100" | bc)
Finally, note that with your last sed command the file will not be edited in place, as the -i
flag is missing.
Upvotes: 1
Reputation: 339
Use double quotes instead of single quotes, because single quotes limit substitution of variables. In your case, what you want is:
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
If you want to do a float division in bash
, you should use a tool such as bc
. In your case, for example:
ok_rate=$(echo "scale=2; $ok_total/$((ok_total+error_total))" | bc)
Upvotes: 0