This section will present a relatively simple version of the find(1) command-line utility written in Go.
The name of the program is goFind.go, and it will be presented in four parts. The code of goFind.go will support two command-line options. The -d option prints a star character in front of paths that are directories, while the -f parameter prints a plus character in front of paths that are regular files.
The first code portion of goFind.go is shown in the following Go code:
package main import ( "flag" "fmt" "os" "path/filepath" )
As you can see, the goFind.go program uses the flag package for efficiently dealing with its command-line parameters.
The second part of goFind.go contains the following code:
var minusD bool = false var minusF bool = false func walk(path string, info os.FileInfo, err error) error { fileInfo, err := os.Stat(path) if err != nil { return err } mode := fileInfo.Mode() if mode.IsRegular() && minusF { fmt.Println("+", path) return nil } if mode.IsDir() && minusD { fmt.Println("*", path) return nil } fmt.Println(path) return nil }
As both minusD and minusF should be accessible from everywhere in the program, including the walk() function, I have decided to make both of them global variables. The IsDir() function helps you identify directories and IsRegular() helps you identify regular files.
The third code segment of goFind.go follows next:
func main() { starD := flag.Bool("d", false, "Signify directories") plusF := flag.Bool("f", false, "Signify regular files") flag.Parse() flags := flag.Args() Path := "." if len(flags) == 1 { Path = flags[0] }
The last part of goFind.go is shown in the following Go code:
minusD = *starD minusF = *plusF err := filepath.Walk(Path, walk) if err != nil { fmt.Println(err) os.Exit(1) } }
Executing goFind.go will create the following type of output:
$ go run goFind.go -d -f /tmp/ * /tmp/ + /tmp/.keystone_install_lock * /tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D * /tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116 + /tmp/ExmanProcessMutex + /tmp/adobegc.log /tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk * /tmp/com.apple.launchd.h3Izgq45dz /tmp/com.apple.launchd.h3Izgq45dz/Listeners * /tmp/lilo.46843 + /tmp/swtag.log /tmp/textmate-501.sock $ go run goFind.go -f /tmp/ /tmp/ + /tmp/.keystone_install_lock /tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D /tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116 + /tmp/ExmanProcessMutex + /tmp/adobegc.log /tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk /tmp/com.apple.launchd.h3Izgq45dz /tmp/com.apple.launchd.h3Izgq45dz/Listeners /tmp/lilo.46843 + /tmp/swtag.log /tmp/textmate-501.sock $ go run goFind.go /tmp/ /tmp/ /tmp/.keystone_install_lock /tmp/5580C65A-E7E2-4B27-AD91-506F85545E1D /tmp/569A57CB-8FD3-4879-A6A3-B86116CB0116 /tmp/ExmanProcessMutex /tmp/adobegc.log /tmp/com.adobe.AdobeIPCBroker.ctrl-mtsouk /tmp/com.apple.launchd.h3Izgq45dz /tmp/com.apple.launchd.h3Izgq45dz/Listeners /tmp/lilo.46843 /tmp/swtag.log /tmp/textmate-501.sock
The output of goFind.go contains every kind of file that can be found under the specified root directory, including sockets and symbolic links. If you make the necessary changes to the walk() function, you can tell goFind.go to print only the information that really interests you. This is left as an exercise for you to do it on your own.