解析我的bash脚本的输出并另存为CSV

时间:2018-07-09 20:28:06

标签: regex string bash csv parsing

我有一个bash脚本,它通过SSH连接到服务器列表(给定.txt文件),并在每个服务器内运行另一个脚本,并显示结果。但是我需要从输出中解析详细数据,并最终将一些有意义的结果另存为.CSV文件。

这是我的主要脚本:

set +e
while read line
do
    ssh myUser@"$line" -t 'sudo su /path/to/script.sh' < /dev/null
done < "/home/listOfServers.txt"

listOfServers.txt所在的地方

server1
server2
server3

运行我的脚本的输出看起来像这样,一个接一个显示每个服务器的结果。

     SNAME:WORKFLOW_APS_001     |10891    | Alive:2018-06-18:06:54          |TCP
     SNAME:WORKFLOW_APSWEB_001     |11343    | Alive:2018-06-18:06:54          |TCP
    Processes in Instance: WORKFLOW_OHS_002
    WORKFLOW_OHS_002                 | OHS                |    8925 | Alive    |  852960621 |  1367120 | 510:11:51 | http:9881
    Processes in Instance: WORKFLOW_OHS_003
    WORKFLOW_OHS_003                 | OHS                |    9187 | Alive    | 2041606684 |  1367120 | 510:11:51 | http:9883
     SNAME:WORKFLOW_RPSF_001     |10431    | Alive:2018-06-18:06:55          |TCP
     SNAME:WORKFLOW_SCPTL_001     |9788    | Alive:2018-06-18:06:55          |TCP
...

从此输出中,我仅需要OHS名称及其状态,并将其与原始服务器的名称一起保存为CSV。我的模式如下所示:我需要查看每一行,如果该行不包含"Processes in Instance""SNAME",则根据空间进行拆分,并抓住第一行(OHS名称)和第四个字段(状态)。因此,我的CSV如下所示:

server1, WORKFLOW_OHS_002, Alive
server1, WORKFLOW_OHS_003, Alive
server2, .....
...

如何修改我的bash来做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以使用awk

while read -r line; do
    ssh myUser@"$line" -t 'sudo su /path/to/script.sh' < /dev/null |
    awk -v s="$line" -F '|' -v OFS=', ' '!/^[[:blank:]]*SNAME:/ && NF>2 {
       gsub(/^[[:blank:]]+|[[:blank:]]+$/, "");
       gsub(/[[:blank:]]*\|[[:blank:]]*/, "|");
       print s, $1, $4
    }'
done < "/home/listOfServers.txt"

编辑:根据下面的评论,您可以执行以下操作来处理错误情况:

while read -r line; do
    out=$(ssh myUser@"$line" -t 'sudo su /path/to/script.sh' < /dev/null 2>&1)
    if [[ -z $out ]]; then
       echo "$line, NULL, NULL"
    elif [[ $out == *"timed out"* ]]; then
       echo "$line, FAIL, FAIL"
    else
       awk -v s="$line" -F '|' -v OFS=', ' '!/^[[:blank:]]*SNAME:/ && NF>2 {
          gsub(/^[[:blank:]]+|[[:blank:]]+$/, "");
          gsub(/[[:blank:]]*\|[[:blank:]]*/, "|");
          print s, $1, $4
       }' <<< "$out"
    fi
done < "/home/listOfServers.txt"

答案 1 :(得分:1)

可以尝试的东西-祝你好运。

while read line
do  ssh myUser@"$line" -t 'sudo su /path/to/script.sh' < /dev/null |
        sed -E "/Processes in Instance/d; /SNAME/d;
        s/^ *([^| ]*) *[|][^|]*[|][^|]*[|] *([^| ]*).*/$line,\1,\2/;" 
done < "/home/listOfServers.txt"

您应该能够对此进行改进。 :)