More Go
Still learning and playing with Go, I’ve
rewritten my
cat experiment, to
use a *bufio.Reader
, which is more correct I think. I’m also slowly
wrapping my mind around the concept of
Interfaces. As a
non-OO programmer (C and non-OO Perl) is starting to see why this is
useful.
So today’s exercises:
- Write a cat implementation in Go. See below.
- Write a grep implementation in Go. See below.
Cat in go⌗
package main
// A implementation of cat in Go
import (
"os";
"fmt";
"bufio";
"flag";
)
var numberFlag = flag.Bool("n", false, "number each line")
func cat(r *bufio.Reader) bool {
i := 1;
for {
buf, e := r.ReadBytes('\n');
if e == os.EOF {
break
}
if *numberFlag {
fmt.Fprintf(os.Stdout, "%5d %s", i, buf);
i++
} else {
fmt.Fprintf(os.Stdout, "%s", buf)
}
}
return true;
}
func main() {
flag.Parse();
if flag.NArg() == 0 {
cat(bufio.NewReader(os.Stdin))
}
for i := 0; i < flag.NArg(); i++ {
f, e := os.Open(flag.Arg(i), os.O_RDONLY, 0);
if e != nil {
fmt.Fprintf(os.Stderr, "%s: error reading from %s: %s\n",
os.Args[0], flag.Arg(i), e.String());
continue;
}
if !cat(bufio.NewReader(f)) {
os.Exit(1)
}
}
}
Grep in go⌗
package main
// A implementation of Unix grep in Go
// TODO(mg) better error handling
import (
"os";
"fmt";
"bufio";
"regexp";
"flag";
)
var numberFlag = flag.Bool("n", false, "number each line")
var filenameFlag = flag.Bool("l", false, "print names of matching files")
func grep(r *bufio.Reader, reg string) (match bool) {
i := 0;
for {
buf, e := r.ReadBytes('\n');
i++;
if e == os.EOF {
break
}
if m, _ := regexp.Match(reg, buf); m == true {
match = true;
if *filenameFlag {
return match
}
if *numberFlag {
fmt.Fprintf(os.Stdout, "%5.d: %s", i, buf)
} else {
fmt.Fprintf(os.Stdout, "%s", buf)
}
}
}
return match;
}
func main() {
flag.Parse();
if flag.NArg() < 1 {
fmt.Fprintf(os.Stderr, "%s: missing regexp\n", os.Args[0]);
os.Exit(1);
}
if flag.NArg() == 1 {
if grep(bufio.NewReader(os.Stdin), flag.Arg(0)) {
if *filenameFlag {
fmt.Fprintf(os.Stdout, "(standard input)\n");
}
}
}
for i := 1; i < flag.NArg(); i++ {
f, e := os.Open(flag.Arg(i), os.O_RDONLY, 0);
if e != nil {
fmt.Fprintf(os.Stderr, "%s: error reading from %s: %s\n",
os.Args[0], flag.Arg(i), e.String());
continue;
}
if grep(bufio.NewReader(f), flag.Arg(0)) {
if *filenameFlag {
fmt.Fprintf(os.Stdout, "%s\n", flag.Arg(i))
}
}
}
}
Read other posts