Skip to content

Instantly share code, notes, and snippets.

@vedantroy
Created December 22, 2022 06:02
Show Gist options
  • Save vedantroy/5c995b009c195fbd5f16e030fb8ff580 to your computer and use it in GitHub Desktop.
Save vedantroy/5c995b009c195fbd5f16e030fb8ff580 to your computer and use it in GitHub Desktop.
// ChatGPT is going to take my job
package main
import (
"bufio"
"flag"
"fmt"
"os"
"regexp"
"sort"
"strconv"
)
type sortableLine struct {
key string
value string
}
type sortableLines []sortableLine
func toInt(s string) int {
i, err := strconv.Atoi(s)
if err != nil {
fmt.Fprintln(os.Stderr, "Error converting to int:", err)
os.Exit(1)
}
return i
}
func main() {
// Parse command-line options
regexStr := flag.String("regex", "", "Use regex to extract sort key")
failOnNoMatch := flag.Bool("fail", false, "Fail if regex does not match")
numericSort := flag.Bool("numeric", false, "Sort numerically")
flag.Parse()
// Compile the regex
var regex *regexp.Regexp
if *regexStr != "" {
var err error
regex, err = regexp.Compile(*regexStr)
if err != nil {
fmt.Fprintln(os.Stderr, "Error compiling regex:", err)
os.Exit(1)
}
}
// Read all the lines from stdin
scanner := bufio.NewScanner(os.Stdin)
lines := sortableLines{}
for scanner.Scan() {
line := scanner.Text()
if regex != nil {
// Extract the sort key from the line using the regex
matches := regex.FindStringSubmatch(line)
if matches == nil {
if *failOnNoMatch {
fmt.Fprintln(os.Stderr, "Regex did not match line:", line)
os.Exit(1)
}
continue
}
switch len(matches) {
case 1:
lines = append(lines, sortableLine{key: line, value: line})
case 2:
lines = append(lines, sortableLine{key: matches[1], value: line})
default:
fmt.Fprintln(os.Stderr, "Regex matched more than one group:", line)
os.Exit(1)
}
} else {
lines = append(lines, sortableLine{key: line, value: line})
}
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "Error reading from stdin:", err)
os.Exit(1)
}
if *numericSort {
sort.Slice(lines, func(i, j int) bool {
// convert the keys to integers
// if they aren't valid ints; throw an error
return toInt(lines[i].key) < toInt(lines[j].key)
})
} else {
sort.Slice(lines, func(i, j int) bool {
return lines[i].key < lines[j].key
})
}
for _, line := range lines {
fmt.Println(line.value)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment