-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
124 lines (115 loc) · 3.12 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"github.com/dustin/go-humanize"
"github.com/mattn/go-isatty"
)
var (
flagfileOnly = flag.Bool("f", false, "Select fileonly not including directories")
flagQuotation = flag.Bool("q", false, "Enclose filename with double-quotations")
flagNameOnly = flag.Bool("1", false, "Show nameonly without size and timestamp")
flagList = flag.Bool("l", false, "Show size and timestamp")
flagStartDir = flag.String("d", ".", "Set start Directory")
flagExecCmd = flag.String("x", "", "Execute a command replacing {} to FILENAME")
flagExecWithQ = flag.String("X", "", `Execute a command replacing {} to "FILENAME" (same as -x,-v and -q)`)
flagIn = flag.Duration("in", 0, "Files modified in the duration such as 300ms, -1.5h or 2h45m")
flagNotIn = flag.Duration("notin", 0, "Files modified not in the duration such as 300ms, -1.5h or 2h45m")
flagIgnoreDots = flag.Bool("ignoredots", false, "Ignore files and directory starting with dot")
flagVerbose = flag.Bool("v", false, "verbose (use with -x)")
)
func eachfile(dirname string, walk func(string, os.FileInfo) error) {
children, err := ioutil.ReadDir(dirname)
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %s\n", dirname, err)
return
}
for _, child := range children {
childpath := filepath.Join(dirname, child.Name())
if err := walk(childpath, child); err != nil {
fmt.Fprintf(os.Stderr, "%s: %s\n", childpath, err)
}
}
}
func main1(args []string) error {
patterns := make([]string, len(args))
for i := 0; i < len(args); i {
patterns[i] = strings.ToUpper(args[i])
}
rich := isatty.IsTerminal(os.Stdout.Fd())
if *flagList {
rich = true
}
if *flagNameOnly {
rich = false
}
var walk func(string, os.FileInfo) error
walk = func(path string, info os.FileInfo) error {
name := filepath.Base(path)
if name == "." || name == ".." {
return nil
}
if *flagIgnoreDots && name[0] == '.' {
return nil
}
if info.IsDir() {
eachfile(path, walk)
}
if *flagfileOnly && info.IsDir() {
return nil
}
if len(patterns) > 0 {
matched := false
for _, pattern := range patterns {
m, err := filepath.Match(pattern, strings.ToUpper(name))
if err == nil && m {
matched = true
break
}
}
if !matched {
return nil
}
}
if *flagIn != 0 && time.Now().Sub(info.ModTime()) > *flagIn {
return nil
}
if *flagNotIn != 0 && time.Now().Sub(info.ModTime()) <= *flagNotIn {
return nil
}
if *flagExecWithQ != "" {
*flagExecCmd = *flagExecWithQ
*flagQuotation = true
*flagVerbose = true
}
if *flagQuotation {
path = `"` path `"`
}
if *flagExecCmd != "" {
cmdline := strings.Replace(*flagExecCmd, "{}", path, -1)
if *flagVerbose {
fmt.Fprintln(os.Stderr, cmdline)
}
system(cmdline)
} else {
fmt.Println(path)
if rich {
fmt.Printf("s %s\n", humanize.Comma(info.Size()), info.ModTime().String())
}
}
return nil
}
eachfile(*flagStartDir, walk)
return nil
}
func main() {
flag.Parse()
if err := main1(flag.Args()); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
}