最近在看《GOPL》,在第一章讲到命令行参数可以获取参数并输出,便想到工作中偶尔会遇到需要把一段字符串的所有符号都删除的情况,便想是不是刚好可以用 Go 实现,权当练手。

命令行参数获取和输出

下面是书内的例子,可以实现从命令行获取数据并原样输出。

// arg.go
func main

import (
    "fmt"
    "os"
    "strings"
)

func main() {
    // 获取命令行参数并合并
    str := strings.Join(os.Args[1:], " ")
    fmt.Println(str)
}

使用 Replace 替换

如果只是替换指定的符号,只要在原来的下面再加一行代码即可实现:

// arg.go
func main() {
    str := strings.Join(os.Args[1:], " ")
    // 替换带有 - 的字符
    str = strings.Replace(str, "-", -1)
    fmt.Println(str)
}
$ go run arg.go Hello-world
Helloworld

使用正则表达式替换

Replace 只能匹配指定符号,如果想匹配任意符号,则需要用正则表达式实现。

// arg.go
package main

import (
    "fmt"
    "os"
    "strings"
    "regexp"
)

func main() {
    // 正则匹配规则,匹配标点符号
    re, _ := regexp.Compile(`[[:punct:]]`)
    str := strings.Join(os.Args[1:], " ")
    // 替换所有符合匹配规则的符号
    str = re.ReplaceAllString(str, "")
    fmt.Println(str)
}

从剪贴板获取和输出

在练习书中的例子时,发现如果从命令行参数获取,不仅在运行时需要手动粘贴,操作完毕后还需要手动复制;是不是可以直接读取剪切板的内容,并在操作完成后自动复制。

pbpaste

在 pbpaste 中保存着 macOS 剪贴板的数据,如果在终端中输入pbpaste会返回当前剪切板的内容,而在 Golang 里面可以借用exec.Command达到目的。

// clip_paste.go
package main

import (
	"fmt"
	"os/exec"
)

func main() {
	// 返回可执行的 Cmd 方法
	cmd := exec.Command("pbpaste")
	// 返回标准输出和标准错误输出
	str, _ := cmd.Output()
	fmt.Println(string(str))
}

运行时,将在终端打印当前剪贴板中的字符。

pbcopy

向剪贴板写入数据。

// clip_copy.go
package main

import (
	"io"
	"os/exec"
)

func main() {
	cmd := exec.Command("pbcopy")
	str, _ := cmd.StdinPipe()

	go func() {
		defer str.Close()
		// 把指定内容写入 str
		io.WriteString(str, "Hello world")
	}()
	cmd.CombinedOutput()
}

最后

为了使代码更简要,上面省略了错误处理,下面是完整的代码:

package main

import (
	"io"
	"log"
	"os/exec"
	"regexp"
)

func main() {
	re, _ := regexp.Compile(`[[:punct:]]`)
	str := re.ReplaceAllString(readClip(), "")
	writeClip(str)
}

func getCmd(cmd string) *exec.Cmd {
	return exec.Command(cmd)
}

func readClip() string {
	cmd := getCmd("pbpaste")
	str, err := cmd.Output()
	if err != nil {
		log.Fatal(err)
	}
	return string(str)
}

func writeClip(text string) {
	cmd := getCmd("pbcopy")
	str, err := cmd.StdinPipe()
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		defer str.Close()
		io.WriteString(str, text)
	}()

	_, err = cmd.CombinedOutput()
	if err != nil {
		log.Fatal(err)
	}
}

当运行clip时,便会自动删除剪贴板中的所有符号,并自动拷贝清理后结果。不过目前上面的代码仅对 macOS 有效,因为 Windows 和 Linux 接口不同所致,如果不想折腾,在 Github 有封装好的代码可以直接使用。

信息

版本

  • Golang:go1.14.1 darwin/amd64
  • macOS Catalina:10.15.4

参考