【Go语言小工具】Mikrotik批量替换程序

Go语言非常适合做一些命令行小工具,编译下面这个代码生成golang-mikrotik-replace.exe文件

package main

import (
	"flag"
	"fmt"
	"net/url"
	"os"
	"strings"

	"github.com/go-routeros/routeros"
)

func main() {
	// 默认 URL 来自环境变量
	defaultURL := os.Getenv("MIKROTIK_URL")
	if defaultURL == "" {
		defaultURL = "//user:pass@127.0.0.1:8728/ip/address"
	}

	// 命令行参数
	rawURL := flag.String("url", defaultURL, "Mikrotik API URL (格式: //user:pass@host:port/path)")

	// 覆盖选项
	overrideUser := flag.String("user", "", "覆盖用户名")
	overridePass := flag.String("pass", "", "覆盖密码")
	overrideHost := flag.String("host", "", "覆盖整个 host (hostname:port)")
	overrideHostname := flag.String("hostname", "", "覆盖 hostname,不改端口")
	overridePort := flag.String("port", "", "覆盖端口,不改 hostname")
	overridePath := flag.String("path", "", "覆盖路径 (例如 /ip/address)")

	// 逻辑参数
	field := flag.String("field", "address", "需要替换的字段")
	search := flag.String("search", "", "要查找的字符串")
	target := flag.String("target", "", "替换后的字符串")

	debug := flag.Bool("debug", false, "打印最终 URL 调试信息")

	flag.Parse()

	// 解析 URL
	parsedURL, err := url.Parse(*rawURL)
	if err != nil {
		panic(err)
	}

	// 覆盖 user/pass
	if *overrideUser != "" {
		parsedURL.User = url.UserPassword(*overrideUser, *overridePass)
	} else if *overridePass != "" && parsedURL.User != nil {
		parsedURL.User = url.UserPassword(parsedURL.User.Username(), *overridePass)
	}

	// 覆盖 Host/Hostname/Port
	if *overrideHost != "" {
		// 覆盖整个 host:port
		parsedURL.Host = *overrideHost
	} else {
		// 覆盖 hostname
		if *overrideHostname != "" {
			port := parsedURL.Port()
			if port != "" {
				parsedURL.Host = fmt.Sprintf("%s:%s", *overrideHostname, port)
			} else {
				parsedURL.Host = *overrideHostname
			}
		}
		// 覆盖 port
		if *overridePort != "" {
			hostOnly := parsedURL.Hostname()
			parsedURL.Host = fmt.Sprintf("%s:%s", hostOnly, *overridePort)
		}
	}

	// 覆盖 path
	if *overridePath != "" {
		parsedURL.Path = *overridePath
	}

	// 拆分 user/pass
	user := ""
	pass := ""
	if parsedURL.User != nil {
		user = parsedURL.User.Username()
		pass, _ = parsedURL.User.Password()
	}
	apiAddr := parsedURL.Host
	runPath := parsedURL.Path

	if *debug {
		fmt.Println("DEBUG INFO:")
		fmt.Println("  User:", user)
		fmt.Println("  Pass:", pass)
		fmt.Println("  Host:", apiAddr)
		fmt.Println("  Hostname:", parsedURL.Hostname())
		fmt.Println("  Port:", parsedURL.Port())
		fmt.Println("  Path:", runPath)
		fmt.Println("  Field:", *field)
		fmt.Println("  Search:", *search)
		fmt.Println("  Target:", *target)
		fmt.Println()
	}

	// 连接 Mikrotik API
	c, err := routeros.Dial(apiAddr, user, pass)
	if err != nil {
		panic(err)
	}
	defer c.Close()

	re, err := c.Run(runPath + "/print")
	if err != nil {
		panic(err)
	}

	// 遍历结果
	for _, sentence := range re.Re {
		id := sentence.Map[".id"]
		source := sentence.Map[*field]
		replaced := strings.ReplaceAll(source, *search, *target)
		if source != replaced {
			fmt.Printf("替换 %s -> %s\n", source, replaced)
			_, err = c.Run(runPath+"/set",
				fmt.Sprintf("=.id=%s", id),
				fmt.Sprintf("=%s=%s", *field, replaced),
			)
			if err != nil {
				panic(err)
			}
		}
	}
}

首先设置环境变量MIKROTIK_URL=//user:pass@127.0.0.1:8728/ip/address
然后通过下面的命令行示例代码即可执行操作

golang-mikrotik-replace.exe -hostname 100.100.0.113 -path /ip/address -field address -search 172.17.0. -target 172.18.0.
golang-mikrotik-replace.exe -hostname 100.100.0.113 -path /ip/route -field gateway -search 172.17.0. -target 172.18.0.
golang-mikrotik-replace.exe -hostname 100.100.0.113 -path /ip/firewall/nat -field to-addresses -search 172.17.0. -target 172.18.0.
golang-mikrotik-replace.exe -hostname 100.100.0.113 -path /ip/firewall/nat -field dst-address -search 172.17.0. -target 172.18.0.
posted on 2025-10-03 01:54  项希盛  阅读(3)  评论(0)    收藏  举报