Skip to content

Instantly share code, notes, and snippets.

@mendelgusmao
Last active November 5, 2022 12:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mendelgusmao/2410b2a2e1a718d64b2f to your computer and use it in GitHub Desktop.
Save mendelgusmao/2410b2a2e1a718d64b2f to your computer and use it in GitHub Desktop.
.zsh_history merge+remove duplicate lines
package main
import (
"fmt"
"io/ioutil"
"os"
"regexp"
"sort"
"strconv"
"strings"
"github.com/MendelGusmao/smart"
)
var lineRE = regexp.MustCompile(`: (\d+):\d+;.*`)
type Command struct {
ts int
line string
}
func (c Command) escape() string {
if strings.Contains(c.line, "\n") {
return strings.Replace(c.line, "\n", "\\\n", -1)
}
return c.line
}
type History []Command
func (h History) Len() int { return len(h) }
func (h History) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h History) Less(i, j int) bool { return h[i].ts < h[j].ts }
func main() {
commands := make(map[string]Command)
args := os.Args[1:]
if len(args) < 2 {
fmt.Println("You need to provide at least 2 arguments")
os.Exit(1)
}
for _, file := range args {
content, err := ioutil.ReadFile(file)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
for _, s := range smart.Split(string(content), "\n", "\\") {
if lineRE.MatchString(s) {
ts, err := strconv.Atoi(lineRE.FindStringSubmatch(s)[1])
if err != nil {
fmt.Println("Timestamp error @", s)
os.Exit(1)
}
if _, ok := commands[s]; ok {
continue
}
commands[s] = Command{ts, s}
} else {
fmt.Println("Error @", s)
os.Exit(1)
}
}
}
history := make(History, 0)
for _, command := range commands {
history = append(history, command)
}
sort.Sort(history)
for _, command := range history {
fmt.Println(command.escape())
}
}
@mendelgusmao
Copy link
Author

go run main.go .zsh_history_1 .zsh_history_2 .zsh_history_N... > .zsh_history_new

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment