Bash 以 csv 格式输出 ping

Bash ping output in csv format

我的目标是将 ping 命令的输出(最后两行)转换为 CSV 样式。

这里有一些例子:

如果丢包率低于 100% <

 URL, PacketLoss, Min, Average, Max, Deviation

如果丢包率达到100%

 URL, 100, -1, -1, -1, -1

我的脚本如下,但是当丢包率为 100% 时,输出为:

URL, 100, 

所以问题出在if语句,因为它没有进入elif,我使用与检查地址是否已满(是否为"www.")相同的语法。

你能看看吗,因为我尝试了很多东西,但都没有用。

我的脚本:

#!/bin/bash

declare site=''
declare result='';

if [[ "" == "www."* ]]; then
        site="";
else
        site="www.";
fi

result="$site";

pingOutput=$(ping $site -c10 -i0.2 -q| tail -n2);

fl=true;

while IFS= read -r line
do

# !!! The problem is here, the if statement is not working properly and I do not know why !!!

        if [ "$fl" == "true" ]; then
                result="$result $(echo "$line" | cut -d',' -f3 | cut -d" " -f2 | sed -r 's/%//g')";
                fl=false;
        elif [[ "$line" == "ms"* ]]; then
                result="$result $(echo "$line" | cut -d' ' -f4 | sed -r 's/\// /g')";
        else
                result="$result -1 -1 -1 -1";
        fi
done <<< "$pingOutput"

echo "$result";

由于从未处理过 pingOutput 的第二行(之前循环结束),因此从未执行将 -1 添加到输出的操作。

由于这个问题,我决定捕获失败百分比并在没有数据包返回时采取行动(100%),我还简化了您最初使用的一些表达式。

我调查了脚本并提出了以下解决方案:

#!/bin/bash

declare site=''
declare result=''
declare prctg=''

[[ "" == "www."* ]] && site="" || site="www."

result="$site"

pingOutput=$(ping $site -c10 -i0.2 -q| tail -n2)

fl=true

while IFS= read -r line
do
# !!! The problem is here, the if statement is not working properly and I do not know why !!!
echo $line
if [ "$fl" == "true" ]
    then
        prctg=$(echo "$line" | grep -Po "[0-9]{0,3}(?=%)")
        result="$result $prctg"
        fl=false
    fi
if [ "$prctg" == "100" ]
    then
        result="$result -1 -1 -1 -1"
    else
        result="$result $(echo "$line" | cut -d' ' -f4 | sed -r 's/\// /g')"
    fi
done <<< "$pingOutput"

echo "$result"

这是一个很老的问题,但我今天偶然发现了它。下面我粘贴了上述脚本的一个轻微修改版本,它修复了 if 问题并适用于 Mac OS.

P.S。您可以取消注释 # prctg=100.0% 行以查看 if 工作。

#!/bin/bash

declare site=''
declare result=''
declare prctg=''

[[ "" == "www."* ]] && site="" || site="www."

result="$site"

pingOutput=$(ping $site -c10 -i0.2 -q | tail -n2)

fl=true

while IFS= read -r line
do
  #echo $line
  if [ "$fl" == "true" ]
  then
    prctg=$(echo "$line" | grep -Eo "[.[:digit:]]{1,10}%")
    result="$result,$prctg"
    fl=false
   # prctg=100.0%
  else
    if [ "$prctg" == "100.0%" ]
    then
      result="$result,-1,-1,-1,-1"
    else
      result="$result,$(echo "$line" | cut -d' ' -f4 | sed -E 's/\//,/g')"
    fi
  fi
done <<< "$pingOutput"

echo "$result"

希望对未来的人有所帮助! :)