2020年6月21日日曜日

開発環境

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 コメント:

コメントを投稿