開発環境
- macOS Catalina - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- Go (プログラミング言語)
Go Systems Programming: Master Linux and Unix system level programming with Go (Mihalis Tsoukalos(著)、Packt Publishing)のChapter 5(Files and Directories)、Exercises 7.の解答を求めてみる。
コード
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
)
func excludeName(name string, exclude string) bool {
if exclude == "" {
return false
}
if filepath.Base(name) == exclude {
return true
}
return false
}
func excludeExtentions(name string, extension string) bool {
if extension == "" {
return false
}
base := filepath.Base(name)
s := strings.Split(base, ".")
baseExtension := s[len(s)-1]
if baseExtension == extension {
return true
}
return false
}
func regularExpression(path, regExp string) bool {
if regExp == "" {
return true
}
r, err := regexp.Compile(regExp)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return true
}
matched := r.MatchString(path)
return matched
}
func main() {
minusS := flag.Bool("s", false, "Sockets")
minusP := flag.Bool("p", false, "Pipes")
minusSL := flag.Bool("sl", false, "Symbolic LInks")
minusD := flag.Bool("d", false, "Directories")
minusF := flag.Bool("f", false, "Files")
minusX := flag.String("x", "", "Files")
minusEXT := flag.String("ext", "", "Extentions")
minusRE := flag.String("re", "", "Regular Expression")
minusSIZE := flag.Int64("size", 0, "Size")
flag.Parse()
args := flag.Args()
if len(args) == 0 {
fmt.Fprintln(os.Stderr, "Not enough arguments!")
os.Exit(1)
}
printAll := false
if (*minusS && *minusP && *minusSL && *minusD && *minusF) ||
!(*minusS || *minusP || *minusSL || *minusD || *minusF) {
printAll = true
}
walkFn := func(path string, info os.FileInfo, err error) error {
if excludeName(path, *minusX) {
return nil
}
if excludeExtentions(path, *minusEXT) {
return nil
}
if !regularExpression(filepath.Base(path), *minusRE) {
return nil
}
fileInfo, err := os.Stat(path)
if err != nil {
return err
}
if fileInfo.Size() < *minusSIZE {
return nil
}
if printAll {
fmt.Println(path)
return nil
}
mode := fileInfo.Mode()
if *minusF && mode.IsRegular() {
fmt.Println(path)
return nil
}
if *minusD && mode.IsDir() {
fmt.Println(path)
return nil
}
fileInfo, _ = os.Lstat(path)
mode = fileInfo.Mode()
if *minusSL && (mode&os.ModeSymlink != 0) {
fmt.Println(path)
return nil
}
if *minusP && (mode&os.ModeNamedPipe != 0) {
fmt.Println(path)
return nil
}
if *minusS && (mode&os.ModeSocket != 0) {
fmt.Println(path)
return nil
}
return nil
}
for _, path := range args {
err := filepath.Walk(path, walkFn)
if err != nil {
fmt.Fprintln(os.Stderr, nil)
os.Exit(1)
}
}
}
入出力結果(Zsh、PowerShell、Terminal)
% go build ./reg_exp_find.go
% ./reg_exp_find -d ..
..
../ls
../reg_exp_find
../rm
../traverse_file
../which
% ./reg_exp_find ../ls
../ls
../ls/ls
../ls/ls.go
% ./reg_exp_find -size=1000 ../ls
../ls/ls
../ls/ls.go
% ./reg_exp_find -size=100 ../ls
../ls
../ls/ls
../ls/ls.go
% ./reg_exp_find -size=10000 ../ls
../ls/ls
%
0 コメント:
コメントを投稿