支持管道
在类 Unix 操作系统(如 Linux 和 macOS)中,管道是一种用于进程间通信(IPC)的机制,允许一个进程的输出被用作另一个进程的输入。
在 Shell 命令中,管道由 |
符号表示。当你使用类似 command1 | command2
的命令时,意味着 command1
的标准输出被连接到 command2
的标准输入。
例如:
cat file.txt | grep "pattern"
在此命令中,file.txt
的内容被作为输入传递到 grep
命令,该命令搜索指定的模式。
修改 main.go 以使file_path
参数可选:
@@ -12,7 +12,7 @@ import (
func main() {
// Set custom usage message
flag.Usage = func() {
- fmt.Fprintf(os.Stderr, "Usage: %s [options] pattern file_path\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, "Usage: %s [options] pattern [file_path]\n", os.Args[0])
fmt.Println("Options:")
flag.PrintDefaults()
}
@@ -30,12 +30,15 @@ func main() {
// pattern - The pattern to search for
// file_path - The path to the file to search in
args := flag.Args()
- if len(args) < 2 {
- fmt.Println("Both pattern and file_path are required.")
+ if len(args) < 1 {
+ fmt.Println("Argument `pattern` is required.")
flag.Usage()
os.Exit(0)
}
- pattern, filePath := args[0], args[1]
+ pattern, filePath := args[0], ""
+ if len(args) > 1 {
+ filePath = args[1]
+ }
options := &grep.Options{}
if *ignoreCaseFlag {
文件路径为空时无法做递归搜索,故修改 main.go:
@@ -48,7 +51,7 @@ func main() {
var result grep.MatchResult
var err error
- if *recursiveFlag {
+ if *recursiveFlag && filePath != "" {
result, err = grep.GrepRecursive(pattern, filePath, options)
if err != nil {
log.Fatal("Failed to do recursive grep, error:", err)
在 pkg/grep/search.go 中,当 filePath
为空时,从标准输入读取内容:
func readFileLines(filePath string) ([]string, error) {
var scanner *bufio.Scanner
if filePath == "" { // 从stdin读取,通常是管道
scanner = bufio.NewScanner(os.Stdin)
} else { // 从文件读取
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
// 创建一个扫描器进行按行读取
scanner = bufio.NewScanner(file)
}
var lines []string
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
if err := scanner.Err(); err != nil {
return nil, err
}
return lines, nil
}
现在可以执行以下操作:
cat main.go | go run main.go -n result
其结果:
51: var result grep.MatchResult
55: result, err = grep.GrepRecursive(pattern, filePath, options)
60: result, err = grep.Grep(pattern, filePath, options)
67: fmt.Println(grep.GrepCount(result))
69: printResult(result, *lineNumberFlag)
73: func printResult(result grep.MatchResult, lineNumberOption bool) {
75: fileCount := len(result)
77: for filePath, items := range result {
重新安装后,你的 gorep
也可以支持管道。
cat main.go | gorep -n result
其结果与上面相同。