原创学习

使用GO语言实现主机扫描报告自动分类并生成CSV文件

本文阅读 4 分钟
首页 学习 正文

使用GO语言实现主机扫描报告自动分类并生成CSV文件

起因

因客户要求制作一个能够针对主机扫描报告进行自动分类的程序。于是决定使用一小会的时间用GO语言简单写一个。

代码

JSON资产示例

{
    "date": "2022年9月14日 16:32",
    "author": "ZeroKong",
    "email": "admin@zerokong.cn",
    "itAssets": {
        "10.0.0.1": {
            "IP地址": "10.0.0.1",
            "位置": "机房A",
            "部门": "A部门",
            "系统名称": "A系统",
            "负责人": "张三"
        },
        "10.0.0.2": {
            "IP地址": "10.0.0.2",
            "位置": "机房A",
            "部门": "A部门",
            "系统名称": "A系统",
            "负责人": "张三"
        },
        "10.0.0.3": {
            "IP地址": "10.0.0.3",
            "位置": "机房A",
            "部门": "A部门",
            "系统名称": "A系统",
            "负责人": "张三"
        },        
        "10.0.0.4": {
            "IP地址": "10.0.0.4",
            "位置": "机房B",
            "部门": "B部门",
            "系统名称": "B系统",
            "负责人": "李四"
        },
        "10.0.0.5": {
            "IP地址": "10.0.0.5",
            "位置": "机房B",
            "部门": "B部门",
            "系统名称": "B系统",
            "负责人": "李四"
        },
        "10.0.0.6": {
            "IP地址": "10.0.0.6",
            "位置": "机房B",
            "部门": "B部门",
            "系统名称": "B系统",
            "负责人": "李四"
        }
    }
}

GO语言代码

// ************************
// ************************
// 日期:2022年9月14日
// 作者:ZeroKong/东方零食
// ************************
// ************************
package main

import (
    "container/list"
    "encoding/csv"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "os"
)

// 结构体
type Data struct { //带结构标签,反引号来包围字符串
    Date     string              `json:"date"`
    Author   string              `json:"author"`
    Email    string              `json:"email"`
    ItAssets map[string]ItAssets `json:"itAssets"`
}

type ItAssets struct {
    // 位置、部门、负责人、IP地址、系统名称、备注、整改方案字段名称
    Address    string `json:"位置"`
    Department string `json:"部门"`
    Leader     string `json:"负责人"`
    IPAddress  string `json:"IP地址"`
    System     string `json:"系统名称"`
    Remark     string `json:"备注"`
    Plan       string `json:"整改方案"`
}

func main() {
    // 打开文件
    jsonFile, err := os.Open("data.json")
    // 如果打开失败,则终止程序
    if err != nil {
        // 输出错误信息
        fmt.Println("error opening json file")
        return
    }

    // 关闭文件
    defer func(jsonFile *os.File) {
        // 如果关闭失败,则终止程序
        err := jsonFile.Close()
        if err != nil {
            // 输出错误信息
            fmt.Println("error closing json file")
        }
    }(jsonFile)

    // 读取文件内容
    jsonData, err := ioutil.ReadAll(jsonFile)
    // 如果读取失败,则终止程序
    if err != nil {
        // 输出错误信息
        fmt.Println("error reading json file")
        return
    }

    // 将json数据解析到结构体
    var data Data
    err = json.Unmarshal(jsonData, &data)
    if err != nil {
        // 输出错误信息
        fmt.Println("error unmarshalling json data")
        return
    }

    var cvslist list.List
    //遍历扫描报告目录下的文件
    //此处需要优化,不判断文件夹
    files, _ := os.ReadDir("./扫描报告")
    for _, file := range files {
        //去除".doc"字符
        fileName := file.Name()
        fileName = fileName[:len(fileName)-4]
        // map判断key是否存在
        if _, ok := data.ItAssets[fileName]; ok {
            // 存在
            var report []byte
            report, err = json.Marshal(data.ItAssets[fileName])
            cvslist.PushBack(string(report))
            fmt.Println(string(report))
            //判断部门\负责人\系统名称目录是否存在不存在则创建目录
            if _, err := os.Stat("./扫描报告/" + data.ItAssets[fileName].Department + "/" + data.ItAssets[fileName].Leader + "/" + data.ItAssets[fileName].System); os.IsNotExist(err) {
                err := os.MkdirAll("./扫描报告/"+data.ItAssets[fileName].Department+"/"+data.ItAssets[fileName].Leader+"/"+data.ItAssets[fileName].System, os.ModePerm)
                if err != nil {
                    return
                }
            }
            //移动file.Name()到指定目录
            err = os.Rename("./扫描报告/"+file.Name(), "./扫描报告/"+string(data.ItAssets[fileName].Department)+"/"+string(data.ItAssets[fileName].Leader)+"/"+string(data.ItAssets[fileName].System)+"/"+file.Name())
            if err != nil {
                fmt.Println(err)
            }
        } else {
            // 不存在
            //因为在mac下编译有个隐藏文件先忽略,后续使用执行文件后删除判断即可
            if fileName == ".DS_S" {
                fmt.Println("文件名为.DS_S")
            } else {
                fmt.Println(fileName)
                //判断部门\负责人\系统名称目录是否存在不存在则创建目录
                if _, err := os.Stat("./扫描报告/无法核实"); os.IsNotExist(err) {
                    err := os.MkdirAll("./扫描报告/无法核实", os.ModePerm)
                    if err != nil {
                        return
                    }
                }
                //移动file.Name()到指定目录
                err = os.Rename("./扫描报告/"+file.Name(), "./扫描报告/无法核实/"+file.Name())
                if err != nil {
                    fmt.Println(err)
                }
                cvslist.PushBack("{\"位置\":\"\",\"部门\":\"\",\"负责人\":\"\",\"IP地址\":\"" + fileName + "\",\"系统名称\":\"\",\"备注\":\"\",\"整改方案\":\"\"}")
            }
        }
    }

    //将cvslist每一行json中的位置、部门、负责人、IP地址、系统名称、备注、整改方案写入csv文件
    //创建csv文件
    csvFile, err := os.Create("./扫描报告.csv")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer csvFile.Close()

    //写入UTF-8 BOM
    csvFile.WriteString("\xEF\xBB\xBF")
    //写入文件头
    csvWriter := csv.NewWriter(csvFile)
    csvWriter.Write([]string{"位置", "部门", "负责人", "IP地址", "系统名称", "备注", "整改方案"})
    //遍历cvslist
    for e := cvslist.Front(); e != nil; e = e.Next() {
        var data02 ItAssets
        err := json.Unmarshal([]byte(e.Value.(string)), &data02)
        if err != nil {
            fmt.Println(err)
            return
        }

        csvWriter.Write([]string{data02.Address, data02.Department, data02.Leader, data02.IPAddress, data02.System, data02.Remark, data02.Plan})
    }
    csvWriter.Flush()

}

后言

代码比较简单先这么写一下,后续在优化就酱紫。

原创文章,作者:zerokong,如若转载,请注明出处:

https://blog.zerokong.com/%E5%AD%A6%E4%B9%A0/21.html

源码部署部署Gitea
« 上一篇 08-03
《天道图书馆》作者:横扫天涯【TXT】【EPUB】【MOBI】【AZW3】
下一篇 » 09-16