catn.goΒΆ

// catn.go

/*

In the following code, panic us used instead of os.Exit to quit the
program. Calling panic ensures deferred functions are called. Calling
os.Exit skips calling deferred functions.

See https://groups.google.com/forum/#!topic/golang-nuts/_Twwb5ULStM for
discussion of how to get both error codes and deferred functions to work
correctly.

*/
package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

// Split a file name string like "conf.py" into strings "conf" and "py".
func splitAtLastDot(name string) (string, string) {
    dotLoc := strings.LastIndex(name, ".")
    if dotLoc == -1 {
        return name, ""
    }
    return name[:dotLoc], name[dotLoc+1:]
}

func main() {
    //
    // check number of command-line arguments
    //
    nargs := len(os.Args) // os.Args contains command-line arguments
    if nargs != 2 {
        fmt.Println("Error: exactly one filename argument must be provided")
        panic("exited")
    }
    inname := os.Args[1]

    //
    // open the input file
    //
    infile, err := os.Open(inname)
    defer infile.Close() // run this when the function is done

    if err != nil {
        fmt.Printf("Error: cannot open file \"%s\" (%s)", inname, err)
        panic("exited")
    }

    //
    // open the output file
    //
    n, ext := splitAtLastDot(inname)
    outname := n + "-lines." + ext
    outfile, err := os.Create(outname) // deletes existing file with same name
    defer outfile.Close() // run this when the function is done
    if err != nil {
        fmt.Printf("Error: cannot create file \"%s\" (%s)", outname, err)
        panic("exited")
    }

    //
    // create the writer
    //
    writer := bufio.NewWriter(outfile)
    defer writer.Flush() // run this when the function is done

    //
    // process the files line by line with a scanner
    //
    scanner := bufio.NewScanner(infile)
    num := 1
    for scanner.Scan() {
        line := scanner.Text()
        // fmt.Printf("%5d  %s\n", num, line) // uncomment to print to screen
        fmt.Fprintf(writer, "%5d  %s\n", num, line)
        num++
    }
    fmt.Println("Results written to " + outname + ".")
}