为什么Go是CLI工具的理想语言?
想象一下:你需要编写一个在控制台中运行、处理文件、调用API或只是自动化日常工作的工具。你可以选择Python、Node.js或Bash。但如果速度、二进制文件大小和分发简便性至关重要——你的选择是Go CLI工具。
Go编译成一个静态二进制文件。没有依赖,没有“你安装了Python 3.8吗?”的问题。下载即运行。这使得Golang CLI工具成为DevOps世界的事实标准(想想Docker、Kubernetes、Hugo——它们都是用Go编写的)。
在本文中,我们不仅会讨论理论。我们将从零开始创建一个真正的Go控制台工具,它将解析JSON、与HTTP交互并输出漂亮的表格。你将学习如何构建项目、处理错误以及为任何平台编译。
环境设置和项目结构
在编写代码之前,请确保你已安装Go(版本1.21+)。检查方法很简单:
go version为我们的项目创建一个目录。将工具命名为json2table——它将从stdin或文件读取JSON,并以表格形式输出数据。
mkdir json2tablecd json2tablego mod init github.com/your-username/json2table项目结构将是Go开发的经典结构:
main.go— 入口点internal/— 内部逻辑(解析、输出)cmd/— 命令处理代码(如果使用Cobra)
我们将从简单的开始,不使用框架,然后添加标志和帮助信息。
编写工具核心:JSON解析和表格输出
创建文件internal/parser.go。在这里,我们将解析JSON并将其转换为结构体。
package internal
import ( "encoding/json" "fmt" "io")
// Record表示表格中的一行type Record map[string]interface{}
// ParseJSON从reader读取JSON并返回记录切片func ParseJSON(r io.Reader) ([]Record, error) { var data []Record decoder := json.NewDecoder(r) if err := decoder.Decode(&data); err != nil { return nil, fmt.Errorf("JSON解析错误: %w", err) } return data, nil}现在创建internal/table.go用于格式化输出:
package internal
import ( "fmt" "strings" "text/tabwriter" "os")
// PrintTable以对齐的表格形式输出记录func PrintTable(records []Record) { if len(records) == 0 { fmt.Println("没有数据可显示") return }
// 收集所有唯一的键(列标题) headers := make([]string, 0) seen := make(map[string]bool) for _, rec := range records { for key := range rec { if !seen[key] { headers = append(headers, key) seen[key] = true } } }
// 使用tabwriter进行美观输出 w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
// 标题 fmt.Fprintln(w, strings.Join(headers, "\\t"))
// 分隔线 sep := make([]string, len(headers)) for i, h := range headers { sep[i] = strings.Repeat("-", len(h)) } fmt.Fprintln(w, strings.Join(sep, "\\t"))
// 数据 for _, rec := range records { row := make([]string, len(headers)) for i, h := range headers { if val, ok := rec[h]; ok { row[i] = fmt.Sprintf("%v", val) } else { row[i] = "" } } fmt.Fprintln(w, strings.Join(row, "\\t")) }
w.Flush()}