Created
February 14, 2021 08:07
-
-
Save nthery/9ba28821e8a4c54c16bda90396644568 to your computer and use it in GitHub Desktop.
Gotac prints lines from standard input or files in command-line in reverse order
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Gotac prints lines from standard input or files in command-line in reverse order. | |
package main | |
import ( | |
"bufio" | |
"fmt" | |
"os" | |
) | |
func main() { | |
args := os.Args[1:] | |
if len(args) == 0 { | |
tac(os.Stdin, "stdin") | |
} else { | |
for _, path := range args { | |
var f *os.File | |
if path == "-" { | |
f = os.Stdin | |
path = "stdin" | |
} else { | |
var err error | |
f, err = os.OpenFile(path, os.O_RDONLY, 0) | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "cannot open %v: %v\n", path, err) | |
continue | |
} | |
defer f.Close() | |
} | |
tac(f, path) | |
} | |
} | |
} | |
// tac reads f line by line and prints lines in reverse order. | |
// path is used for error handling. | |
func tac(f *os.File, path string) { | |
lines, err := readLines(f) | |
printReverse(lines) | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "error while reading %v: %v\n", path, err) | |
} | |
} | |
// readLines returns a slice containing all lines in f without end-of-line. | |
// If an error occurs, lines contains all lines accumulated before the error. | |
func readLines(f *os.File) ([]string, error) { | |
lines := make([]string, 0, 16) | |
scanner := bufio.NewScanner(f) | |
for scanner.Scan() { | |
lines = append(lines, scanner.Text()) | |
} | |
return lines, scanner.Err() | |
} | |
// printReverse prints lines from end to beginning. | |
func printReverse(lines []string) { | |
for i := len(lines) - 1; i >= 0; i-- { | |
fmt.Println(lines[i]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment