rbfind 1.13 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/rbfind +413 -416
- data/lib/rbfind.rb +568 -731
- data/lib/rbfind/core.rb +82 -0
- data/lib/rbfind/csv.rb +54 -0
- data/lib/{humansiz.rb → rbfind/humansiz.rb} +30 -9
- data/lib/rbfind/table.rb +114 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a6e7b3de72cc2efdb3033593f8ffac176da6dab3395d68594570d08c3992249
|
4
|
+
data.tar.gz: 36f03f0b41bd1180429bd527f0fa7f6a8f8e2897c3f99569fbc6250f3e358baf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b30427e248f24b028eb554b5c5672d96695f7fdec4c87e3ae39343671702c89e02664a78ac6bbc40f101baa348fbebc67c9a5e564f8694d27e9d53b1bc7cd103
|
7
|
+
data.tar.gz: 847dbf390ec156f619b06c1820e5df1ca4d51f89b8ebc7ae06f7a055d98bd734d74a7ae6d122e5c58d5eaa0ce183afba0a70db1856801d62bd413c49988ad6b4
|
data/bin/rbfind
CHANGED
@@ -5,137 +5,423 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
require "rbfind"
|
8
|
+
require "rbfind/humansiz"
|
9
|
+
require "English"
|
10
|
+
require 'getoptlong'
|
8
11
|
|
9
|
-
PROGRAM = <<EOT
|
10
|
-
rbfind #{RbFind::VERSION} -- A find tool using Ruby
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
module RbFind
|
14
|
+
|
15
|
+
class Application
|
16
|
+
|
17
|
+
PROGRAM = <<~EOT
|
18
|
+
rbfind #{RbFind::VERSION} -- A find tool using Ruby
|
19
|
+
|
20
|
+
Author: Bertram Scharpf <software@bertram-scharpf.de>
|
21
|
+
License: BSD
|
22
|
+
EOT
|
23
|
+
|
24
|
+
OPTIONS = [
|
25
|
+
# options arg description
|
26
|
+
[ %w(--help -h), nil, "print this help"],
|
27
|
+
[ %w(--examples -X), nil, "print this help and examples"],
|
28
|
+
[ %w(--version -V), nil, "print version information"],
|
29
|
+
[ %w(--verbose -v), nil, "standard Ruby error reports"],
|
30
|
+
[ %w(--show -o), nil, "just show Ruby block built from options"],
|
31
|
+
[ %w(--bw -w), nil, "black and white on -p or default output"],
|
32
|
+
[ %w(--colored -c), nil, "force color on -p or default output"],
|
33
|
+
[ %w(--depth -d), nil, "yield directory after its contents"],
|
34
|
+
[ %w(--maxdepth -m), :num, "maxium step depth"],
|
35
|
+
[ %w(--follow -y), nil, "follow symbolic links"],
|
36
|
+
[ %w(--nosort -S), nil, "unsorted"],
|
37
|
+
[ %w(--sort-by -s), :str, "sort expression ('n' is name)"],
|
38
|
+
[ %w(--reverse -R), :str, "reverse sort"],
|
39
|
+
[ %w(--require -r), :rb, "require library"],
|
40
|
+
[ %w(--fileutils -U), nil, "include FileUtils module"],
|
41
|
+
[ %w(--puts-path -p), nil, "do 'puts path/cpath' on true block"],
|
42
|
+
[ %w(--ls-l -P), nil, "do 'ls -l' style output on true block"],
|
43
|
+
[ %w(--wider -+), nil, "widen fields in long output format (--ls-l)"],
|
44
|
+
[ %w(--slash -/), nil, "append a slash to directory names"],
|
45
|
+
[ %w(--lines -l), :blk, "surround block by 'lines { |$_,$.| ... }'"],
|
46
|
+
[ %w(--reallines -L), :blk, "same as -l but stop at any null character"],
|
47
|
+
[ %w(--grep -g), :blk, "grep files (implies -pL)"],
|
48
|
+
[ %w(--igrep -G), :blk, "case insensitive grep"],
|
49
|
+
[ %w(--binary -b), nil, "grep even binary files"],
|
50
|
+
[ %w(--no-vcs -C), nil, "prune version control dirs (CVS/.svn/.git)"],
|
51
|
+
[ %w(--no-swap -W), nil, "ignore Vim swapfiles"],
|
52
|
+
[ %w(--skip -k), :lst, "filenames to skip"],
|
53
|
+
[ %w(--demand -D), :lst, "skip all filenames but these"],
|
54
|
+
[ %w(--ext -e), :lst, "skip all filename extensions but these"],
|
55
|
+
[ %w(--visible -I), nil, "skip all hidden (starting with .dot)"],
|
56
|
+
[ %w(--nodirs -N), nil, "skip directories"],
|
57
|
+
[ %w(--begin -B), :blk, "eval block before begin"],
|
58
|
+
[ %w(--end -E), :blk, "eval block after end"],
|
59
|
+
[ %w(--file -f), :blk, "read block expression from file"],
|
60
|
+
[ %w(--encoding -K), :str, "encoding extern[:intern] (same as ruby -E)"],
|
61
|
+
]
|
62
|
+
|
63
|
+
def initialize
|
64
|
+
@params = {}
|
65
|
+
envopts = ENV[ "RBFIND_OPTIONS"]
|
66
|
+
$*.unshift *envopts.split if envopts
|
67
|
+
opts = GetoptLong.new *OPTIONS.map { |(long,short),arg,|
|
68
|
+
[long,short,(arg ? GetoptLong::REQUIRED_ARGUMENT : GetoptLong::NO_ARGUMENT)]
|
69
|
+
}
|
70
|
+
opts.ordering = GetoptLong::PERMUTE
|
71
|
+
opts.quiet = true
|
72
|
+
opts.each do |opt,arg|
|
73
|
+
case opt
|
74
|
+
when '--help' then usage ; exit
|
75
|
+
when '--version' then puts PROGRAM ; exit
|
76
|
+
when '--examples' then usage_examples ; exit
|
77
|
+
when '--verbose' then @verbose = true
|
78
|
+
when '--show' then @show = true
|
79
|
+
when '--bw' then @color = false
|
80
|
+
when '--colored' then @color = true
|
81
|
+
when '--depth' then @params[ :depth_first] = true
|
82
|
+
when '--maxdepth' then @params[ :max_depth] = arg.to_i
|
83
|
+
when '--follow' then @params[ :follow] = true
|
84
|
+
when '--nosort' then @params[ :sort] = false
|
85
|
+
when '--sort-by' then @params[ :sort] = instance_eval "proc { |n| #{arg} }"
|
86
|
+
when '--reverse' then @params[ :reverse] = true
|
87
|
+
when '--require' then require arg
|
88
|
+
when '--fileutils' then require "fileutils" ; include FileUtils
|
89
|
+
when '--puts-path' then @puts = true
|
90
|
+
when '--ls-l' then @puts = true ; @wd = 6
|
91
|
+
when '--wider' then @wd = @wd ? @wd.succ : 4
|
92
|
+
when '--slash' then @slash = true
|
93
|
+
when '--lines' then @lines = :plain ; @block = arg
|
94
|
+
when '--reallines' then @lines = :plain ; @real = true ; @block = arg
|
95
|
+
when '--grep' then @lines = :grep ; @block = arg
|
96
|
+
when '--igrep' then @lines = :grep ; @icase = true ; @block = arg
|
97
|
+
when '--binary' then @binary = true
|
98
|
+
when '--no-vcs' then @vcs = true
|
99
|
+
when '--no-swap' then @vim = true
|
100
|
+
when '--skip' then @skip = arg
|
101
|
+
when '--demand' then @demand = arg
|
102
|
+
when '--ext' then @ext = arg
|
103
|
+
when '--visible' then @visible = true
|
104
|
+
when '--nodirs' then @nodirs = true
|
105
|
+
when '--begin' then @blkbegin = arg
|
106
|
+
when '--end' then @blkend = arg
|
107
|
+
when '--file' then @block = File.read arg
|
108
|
+
when '--encoding' then e, i = arg.split ":" ; set_encoding e, i
|
109
|
+
end
|
110
|
+
end
|
111
|
+
@args = $*.dup
|
112
|
+
if @args.empty? and not $stdin.tty? then
|
113
|
+
$stdin.each_line { |l|
|
114
|
+
l.chomp!
|
115
|
+
@args.push l
|
116
|
+
}
|
117
|
+
end
|
118
|
+
build_block
|
119
|
+
rescue GetoptLong::InvalidOption
|
120
|
+
$stderr.puts $!
|
121
|
+
$stderr.puts
|
122
|
+
usage
|
123
|
+
exit 9
|
124
|
+
rescue
|
125
|
+
$stderr.puts $!
|
126
|
+
exit 8
|
127
|
+
end
|
15
128
|
|
129
|
+
def build_block
|
130
|
+
co = color_on $stdout
|
131
|
+
opath = co ? "cpath" : "path"
|
132
|
+
@slash and opath << "!"
|
133
|
+
case @lines
|
134
|
+
when :plain then
|
135
|
+
@puts and @block = "( #@block ) and colsep #{opath}, num, line"
|
136
|
+
@real and @block = "break if ~/\0/o ; #@block"
|
137
|
+
@block = "lines { |line,num| #@block }"
|
138
|
+
|
139
|
+
when :grep then
|
140
|
+
re = Regexp.new @block, @icase && Regexp::IGNORECASE
|
141
|
+
@block = "grep #{re.inspect}"
|
142
|
+
@block << ", true" if co
|
143
|
+
@block << " ; $stdout.flush" unless $stdout.tty?
|
144
|
+
@binary or @block = "not binary? and (#@block)"
|
16
145
|
|
17
|
-
|
146
|
+
else
|
147
|
+
@block ||= if @args.last and not (File.exists? @args.last) then
|
148
|
+
@args.pop.dup
|
149
|
+
else
|
150
|
+
@puts ||= true
|
151
|
+
"true"
|
152
|
+
end
|
153
|
+
if @puts then
|
154
|
+
@block = "( #@block ) and "
|
155
|
+
@block << if @wd then
|
156
|
+
"spcsep stype+modes, user.w#@wd, group.w#@wd, size.w#@wd, " +
|
157
|
+
"mtime.lsish, #{opath} + #{co ? 'carrow' : 'arrow'}.to_s"
|
158
|
+
else
|
159
|
+
"puts #{opath}"
|
160
|
+
end
|
161
|
+
end
|
18
162
|
|
19
|
-
|
20
|
-
# options arg description
|
21
|
-
[ %w(--help -h), nil, "print this help"],
|
22
|
-
[ %w(--examples -X), nil, "print this help and examples"],
|
23
|
-
[ %w(--version -V), nil, "print version information"],
|
24
|
-
[ %w(--verbose -v), nil, "standard Ruby error reports"],
|
25
|
-
[ %w(--show -o), nil, "just show Ruby block built from options"],
|
26
|
-
[ %w(--bw -w), nil, "black and white on -p or default output"],
|
27
|
-
[ %w(--colored -c), nil, "force color on -p or default output"],
|
28
|
-
[ %w(--depth -d), nil, "yield directory after its contents"],
|
29
|
-
[ %w(--maxdepth -m), :num, "maxium step depth"],
|
30
|
-
[ %w(--follow -y), nil, "follow symbolic links"],
|
31
|
-
[ %w(--sort -s), :str, "=reverse/desc/-1,unsorted; default is sorted"],
|
32
|
-
[ %w(--sort-by -S), :str, "sort expression ('name' is name)"],
|
33
|
-
[ %w(--require -r), :rb, "require library"],
|
34
|
-
[ %w(--fileutils -U), nil, "include FileUtils module"],
|
35
|
-
[ %w(--puts-path -p), nil, "do 'puts path/cpath' on true block"],
|
36
|
-
[ %w(--ls-l -P), nil, "do 'ls -l' style output on true block"],
|
37
|
-
[ %w(--wider -+), nil, "widen fields in long output format (--ls-l)"],
|
38
|
-
[ %w(--slash -/), nil, "append a slash to directory names"],
|
39
|
-
[ %w(--lines -l), :blk, "surround block by 'lines { |$_,$.| ... }'"],
|
40
|
-
[ %w(--reallines -L), :blk, "same as -l but stop at any null character"],
|
41
|
-
[ %w(--grep -g), :blk, "grep files (implies -pL)"],
|
42
|
-
[ %w(--igrep -G), :blk, "case insensitive grep"],
|
43
|
-
[ %w(--binary -b), nil, "grep even binary files"],
|
44
|
-
[ %w(--no-vcs -C), nil, "prune version control dirs (CVS/.svn/.git)"],
|
45
|
-
[ %w(--no-swap -W), nil, "ignore Vim swapfiles"],
|
46
|
-
[ %w(--skip -k), :lst, "filenames to skip"],
|
47
|
-
[ %w(--demand -D), :lst, "skip all filenames but these"],
|
48
|
-
[ %w(--ext -e), :lst, "skip all filename extensions but these"],
|
49
|
-
[ %w(--visible -I), nil, "skip all hidden (starting with .dot)"],
|
50
|
-
[ %w(--nodirs -N), nil, "skip directories"],
|
51
|
-
[ %w(--begin -B), :blk, "eval block before begin"],
|
52
|
-
[ %w(--end -E), :blk, "eval block after end"],
|
53
|
-
[ %w(--file -f), :blk, "read block expression from file"],
|
54
|
-
[ %w(--encoding -K), :str, "encoding extern[:intern] (same as ruby -E)"],
|
55
|
-
]
|
56
|
-
|
57
|
-
def usage
|
58
|
-
puts <<EOT
|
59
|
-
Usage:
|
60
|
-
|
61
|
-
rbfind [options] path... 'block'
|
62
|
-
|
63
|
-
EOT
|
64
|
-
OPTIONS.each { |(long,short),arg,desc|
|
65
|
-
puts " %-12s %2s %-5s %s" % [long,short,arg.to_s.upcase,desc]
|
66
|
-
}
|
67
|
-
puts <<'EOT'
|
68
|
-
|
69
|
-
"--" stops option processing.
|
70
|
-
|
71
|
-
The last argument is a block that will be executed on every found
|
72
|
-
file object. It may be omitted; then "puts path" is assumed or "cpath"
|
73
|
-
in case the output is a terminal.
|
74
|
-
|
75
|
-
Default sort order is alphabetical.
|
76
|
-
|
77
|
-
EOT
|
78
|
-
end
|
163
|
+
end
|
79
164
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
$ rbfind -p 'file and age > 1.d'
|
86
|
-
$ rbfind -p '(90.d .. 183.d) === age'
|
87
|
-
|
88
|
-
$ rbfind -Cg require
|
89
|
-
$ rbfind -Cp
|
90
|
-
$ rbfind 'filesize < 100.kB and grep /require/'
|
91
|
-
$ rbfind -g 'define\s*ALLOC_N'
|
92
|
-
$ rbfind myproject -e rb -l '~/require/ and puts $_'
|
93
|
-
|
94
|
-
$ rbfind -pe '.rb c h'
|
95
|
-
$ rbfind /usr/include -e .h -g EACCES
|
96
|
-
$ rbfind -d -m3 -- /mnt/data
|
97
|
-
$ rbfind 'filesize > 10.MiB and colsep size.to_hib, path'
|
98
|
-
|
99
|
-
$ rbfind -S "name =~ /^\.*/ ; $'.downcase"
|
100
|
-
$ rbfind -B '$s=0' -E 'puts $s.to_h' 'filesize {|s|$s+=s}'
|
101
|
-
$ rbfind 'puts path if ext == ".rb"'
|
102
|
-
$ rbfind -p 'ext == ".rb"'
|
103
|
-
$ rbfind /usr/include -p -D '\.h$' -l '~/EACCES/'
|
104
|
-
$ rbfind /usr/include -pD 'pg|pq|postgres' dir
|
105
|
-
$ rbfind 'no_svn ; puts path'
|
106
|
-
$ rbfind 'prune if name == ".svn" ; puts path'
|
107
|
-
$ rbfind -p 'prune if name == ".svn"'
|
108
|
-
$ rbfind myproject 'name[/\.rb$/] and lines { |l,i| l=~/require/ and puts l }'
|
109
|
-
# rbfind /etc 'lines { |l,| l["192.168."] and (puts path ; break) }'
|
110
|
-
$ rbfind /etc 'readable? or raise "Access denied: #{path}" ;
|
111
|
-
> lines { |l,| l["192.168."] and (puts path ; break) }'
|
112
|
-
|
113
|
-
$ rbfind 'col_sep stype+modes, size.w10, path'
|
114
|
-
$ rbfind 'tab_sep stype+modes, size.w10, path'
|
115
|
-
$ rbfind 'spc_sep stype+modes, size.to_h, user, group, mtime.lsish, path'
|
116
|
-
$ rbfind 'spacesep stype+modes, size.to_h, user, group, mtime.lsish, path'
|
117
|
-
$ rbfind 'spacesep stype+modes, size.to_h, user, group, mtime!, path'
|
118
|
-
$ rbfind 'spacesep stype+modes, size.to_h, user, group, mtime.i, path'
|
119
|
-
$ rbfind 'spacesep mtime.u, path'
|
120
|
-
$ rbfind 'spacesep modes, user.w8, group.w8, size.w8, cpath + carrow.to_s'
|
121
|
-
|
122
|
-
$ rbfind 'spacesep digest_md5, size.w8, path'
|
123
|
-
$ rbfind 'spacesep digest_sha256, size.w8, path'
|
124
|
-
|
125
|
-
$ rbfind 'rename name.downcase'
|
126
|
-
$ rbfind 'ext == ".tgz" and rename without_ext+".tar.gz"'
|
127
|
-
|
128
|
-
See the RbFind class documentation or the "rbfind.rb" source file for more
|
129
|
-
sophisticated examples and for a full list of file examination methods.
|
130
|
-
|
131
|
-
Valid units are 1.s, 1.m, 1.h, 1.d, 1.w for time values and
|
132
|
-
1.kB == 1000, 1.kiB == 1024, 1.MB, 1.MiB for file sizes.
|
133
|
-
EOT
|
134
|
-
end
|
165
|
+
osic = File::ALT_SEPARATOR&&Regexp::IGNORECASE
|
166
|
+
if @skip then
|
167
|
+
re = Regexp.new @skip, osic
|
168
|
+
@block.insert 0, "done if name =~ #{re.inspect} ; "
|
169
|
+
end
|
135
170
|
|
171
|
+
if @demand then
|
172
|
+
re = Regexp.new @demand, osic
|
173
|
+
@block.insert 0, "done unless name =~ #{re.inspect} ; "
|
174
|
+
end
|
136
175
|
|
137
|
-
|
138
|
-
|
176
|
+
if @ext then
|
177
|
+
re = Regexp.new '\A\.(' +
|
178
|
+
@ext.split(/ +|,/).map { |e| e[ /\A\.?(.*)\z/, 1] }.join('|') +
|
179
|
+
')\z', osic
|
180
|
+
@block.insert 0, "ext =~ #{re.inspect} or done ; "
|
181
|
+
end
|
182
|
+
|
183
|
+
@visible and @block.insert 0, "visible? or done ; "
|
184
|
+
|
185
|
+
@nodirs and @block.insert 0, "done if dir? ; "
|
186
|
+
|
187
|
+
@vcs and @block.insert 0, "no_vcs ; "
|
188
|
+
@vim and @block.insert 0, "vimswap? and done ; "
|
189
|
+
|
190
|
+
@params[ :error] = proc do
|
191
|
+
case $!
|
192
|
+
when Errno::EPIPE then raise
|
193
|
+
when NameError, TypeError then raise
|
194
|
+
when ArgumentError then raise
|
195
|
+
else show_error $!
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def run
|
201
|
+
if @show then
|
202
|
+
show
|
203
|
+
else
|
204
|
+
execute
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
private
|
209
|
+
|
210
|
+
def usage
|
211
|
+
puts <<~EOT
|
212
|
+
Usage:
|
213
|
+
|
214
|
+
rbfind [options] path... 'block'
|
215
|
+
|
216
|
+
EOT
|
217
|
+
OPTIONS.each { |(long,short),arg,desc|
|
218
|
+
puts " %-12s %2s %-5s %s" % [long,short,arg.to_s.upcase,desc]
|
219
|
+
}
|
220
|
+
puts <<~'EOT'
|
221
|
+
|
222
|
+
"--" stops option processing.
|
223
|
+
|
224
|
+
The last argument is a block that will be executed on every found
|
225
|
+
file object. It may be omitted; then "puts path" is assumed or "cpath"
|
226
|
+
in case the output is a terminal.
|
227
|
+
|
228
|
+
Default sort order is alphabetical.
|
229
|
+
EOT
|
230
|
+
end
|
231
|
+
|
232
|
+
def usage_examples
|
233
|
+
usage
|
234
|
+
puts <<~'EOT'
|
235
|
+
Examples:
|
236
|
+
$ rbfind -p 'file and age < 5.m'
|
237
|
+
$ rbfind -p 'file and age > 1.d'
|
238
|
+
$ rbfind -p '(90.d .. 183.d) === age'
|
239
|
+
|
240
|
+
$ rbfind -Cg require
|
241
|
+
$ rbfind -Cp
|
242
|
+
$ rbfind 'filesize < 100.kB and grep /require/'
|
243
|
+
$ rbfind -g 'define\s*ALLOC_N'
|
244
|
+
$ rbfind myproject -e rb -l '~/require/ and puts $_'
|
245
|
+
|
246
|
+
$ rbfind -pe '.rb c h'
|
247
|
+
$ rbfind /usr/include -e .h -g EACCES
|
248
|
+
$ rbfind -d -m3 -- /mnt/data
|
249
|
+
$ rbfind 'filesize > 10.MiB and colsep size.to_hib, path'
|
250
|
+
|
251
|
+
$ rbfind -S "name =~ /^\.*/ ; $'.downcase"
|
252
|
+
$ rbfind -B '$s=0' -E 'puts $s.to_h' 'filesize {|s|$s+=s}'
|
253
|
+
$ rbfind 'puts path if ext == ".rb"'
|
254
|
+
$ rbfind -p 'ext == ".rb"'
|
255
|
+
$ rbfind /usr/include -p -D '\.h$' -l '~/EACCES/'
|
256
|
+
$ rbfind /usr/include -pD 'pg|pq|postgres' dir
|
257
|
+
$ rbfind 'no_svn ; puts path'
|
258
|
+
$ rbfind 'prune if name == ".svn" ; puts path'
|
259
|
+
$ rbfind -p 'prune if name == ".svn"'
|
260
|
+
$ rbfind myproject 'name[/\.rb$/] and lines { |l,i| l=~/require/ and puts l }'
|
261
|
+
# rbfind /etc 'lines { |l,| l["192.168."] and (puts path ; break) }'
|
262
|
+
$ rbfind /etc 'readable? or raise "Access denied: #{path}" ;
|
263
|
+
> lines { |l,| l["192.168."] and (puts path ; break) }'
|
264
|
+
|
265
|
+
$ rbfind 'col_sep stype+modes, size.w10, path'
|
266
|
+
$ rbfind 'tab_sep stype+modes, size.w10, path'
|
267
|
+
$ rbfind 'spc_sep stype+modes, size.to_h, user, group, mtime.lsish, path'
|
268
|
+
$ rbfind 'p stype+modes, size.to_h, user, group, mtime.lsish, path'
|
269
|
+
$ rbfind 'p stype+modes, size.to_h, user, group, mtime!, path'
|
270
|
+
$ rbfind 'p stype+modes, size.to_h, user, group, mtime.i, path'
|
271
|
+
$ rbfind 'p mtime.u, path'
|
272
|
+
$ rbfind 'p modes, user.w8, group.w8, size.w8, cpath + carrow.to_s'
|
273
|
+
|
274
|
+
$ rbfind 'p digest_md5, size.w8, path'
|
275
|
+
$ rbfind 'p digest_sha256, size.w8, path'
|
276
|
+
|
277
|
+
$ rbfind 'rename name.downcase'
|
278
|
+
$ rbfind 'ext == ".tgz" and rename without_ext+".tar.gz"'
|
279
|
+
|
280
|
+
See the RbFind documentation or the "rbfind.rb" source file for more
|
281
|
+
sophisticated examples and for a full list of file examination methods.
|
282
|
+
|
283
|
+
Valid units are 1.s, 1.m, 1.h, 1.d, 1.w for time values and
|
284
|
+
1.kB == 1000, 1.kiB == 1024, 1.MB, 1.MiB for file sizes.
|
285
|
+
EOT
|
286
|
+
end
|
287
|
+
|
288
|
+
def set_encoding extern, intern = nil
|
289
|
+
Encoding.default_external = extern if extern and not extern.empty?
|
290
|
+
Encoding.default_internal = intern if intern and not intern.empty?
|
291
|
+
[ $stdin, $stdout, $stderr].each do |io|
|
292
|
+
io.set_encoding extern, intern
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def color_on stream
|
297
|
+
@color.nil? ? !File::ALT_SEPARATOR && stream.tty? : @color
|
298
|
+
end
|
299
|
+
|
300
|
+
|
301
|
+
def show_error e
|
302
|
+
co = color_on $stderr
|
303
|
+
$stderr.puts co ? "\e[31m#{e.class}: \e[1m#{e}\e[m" : "#{e.class}: #{e}"
|
304
|
+
end
|
305
|
+
|
306
|
+
def error_handle
|
307
|
+
if @verbose then
|
308
|
+
yield
|
309
|
+
else
|
310
|
+
begin
|
311
|
+
yield
|
312
|
+
rescue ArgumentError
|
313
|
+
show_error $!
|
314
|
+
if $!.message[ "invalid byte sequence"] then
|
315
|
+
$stderr.puts <<~EOT
|
316
|
+
Hint: Try to give a different default encoding by explicitly setting one or
|
317
|
+
by changing the locale.
|
318
|
+
|
319
|
+
$ rbfind -K ascii-8bit ...
|
320
|
+
$ LC_ALL="C" rbfind ...
|
321
|
+
|
322
|
+
Alternatively, you may prefer to scrub the invalid encodings yourself.
|
323
|
+
|
324
|
+
$ rbfind -P 'name.scrub =~ /Fu.ball/'
|
325
|
+
|
326
|
+
EOT
|
327
|
+
end
|
328
|
+
exit 1
|
329
|
+
rescue
|
330
|
+
show_error $!
|
331
|
+
exit 1
|
332
|
+
rescue NoMemoryError, ScriptError, SignalException
|
333
|
+
show_error $!
|
334
|
+
exit 2
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def execute
|
340
|
+
error_handle do
|
341
|
+
eval @blkbegin if @blkbegin
|
342
|
+
b = @block
|
343
|
+
Walk.run *@args, **@params do instance_eval b end
|
344
|
+
eval @blkend if @blkend
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def show
|
349
|
+
puts "arguments:"
|
350
|
+
@args.each { |a| puts_val a }.any? or puts_val "(none)"
|
351
|
+
puts "parameters:"
|
352
|
+
@params.each { |k,v| puts_val k, "=", v }.any? or puts_val "(none)"
|
353
|
+
puts "block:"
|
354
|
+
@block.each_line { |l| puts_val l }
|
355
|
+
end
|
356
|
+
|
357
|
+
INDENT = " "*2
|
358
|
+
|
359
|
+
def puts_val *args
|
360
|
+
l = [ INDENT, *args].join ""
|
361
|
+
puts l
|
362
|
+
end
|
363
|
+
|
364
|
+
end
|
365
|
+
|
366
|
+
|
367
|
+
class Entry
|
368
|
+
|
369
|
+
# Alias the question marks away from all method names because
|
370
|
+
# they're a nuisance on the command line.
|
371
|
+
alias hidden hidden?
|
372
|
+
alias visible visible?
|
373
|
+
alias broken_link broken_link?
|
374
|
+
alias dir dir?
|
375
|
+
alias binary binary?
|
376
|
+
alias bin bin?
|
377
|
+
alias vimswap vimswap?
|
378
|
+
|
379
|
+
def blockdev ; blockdev? ; end
|
380
|
+
def chardev ; chardev? ; end
|
381
|
+
def directory ; directory? ; end
|
382
|
+
def executable ; executable? ; end
|
383
|
+
def executable_real ; executable_real? ; end
|
384
|
+
def file ; file? ; end
|
385
|
+
def grpowned ; grpowned? ; end
|
386
|
+
def owned ; owned? ; end
|
387
|
+
def pipe ; pipe? ; end
|
388
|
+
def readable ; readable? ; end
|
389
|
+
def readable_real ; readable_real? ; end
|
390
|
+
def setgid ; setgid? ; end
|
391
|
+
def setuid ; setuid? ; end
|
392
|
+
def socket ; socket? ; end
|
393
|
+
def sticky ; sticky? ; end
|
394
|
+
def symlink ; symlink? ; end
|
395
|
+
def writable ; writable? ; end
|
396
|
+
def writable_real ; writable_real? ; end
|
397
|
+
def zero ; zero? ; end
|
398
|
+
|
399
|
+
# convenient digest and time format methods
|
400
|
+
alias method_missing_orig method_missing
|
401
|
+
def method_missing sym, *args, &block
|
402
|
+
case sym.to_s
|
403
|
+
when /\Adigest_(.*)/, /\A([a-z]+[0-9]+)\z/ then
|
404
|
+
m = $1
|
405
|
+
d = begin
|
406
|
+
Digest.const_get m.upcase
|
407
|
+
rescue NameError
|
408
|
+
if m =~ /sha\d\d\d/ then m = "sha2" end
|
409
|
+
require "digest/#{m}" and retry
|
410
|
+
raise
|
411
|
+
end
|
412
|
+
e = d.new
|
413
|
+
read 0x1000_0000 do |b| e.update b end
|
414
|
+
e.hexdigest
|
415
|
+
when /\A([amc]time)!\z/ then
|
416
|
+
(send $1).strftime "%Y-%m-%d %H:%M:%S %z"
|
417
|
+
else
|
418
|
+
method_missing_orig sym, *args, &block
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
end
|
423
|
+
|
424
|
+
end
|
139
425
|
|
140
426
|
|
141
427
|
class Time
|
@@ -176,9 +462,6 @@ class String
|
|
176
462
|
else super
|
177
463
|
end
|
178
464
|
end
|
179
|
-
def | width
|
180
|
-
ljust width
|
181
|
-
end
|
182
465
|
# conventient date/time construction
|
183
466
|
def time
|
184
467
|
Time.parse self
|
@@ -201,298 +484,12 @@ class NilClass
|
|
201
484
|
end
|
202
485
|
end
|
203
486
|
|
204
|
-
|
205
|
-
def
|
206
|
-
|
207
|
-
Encoding.default_internal = intern if intern and not intern.empty?
|
208
|
-
[ $stdin, $stdout, $stderr].each do |io|
|
209
|
-
io.set_encoding extern, intern
|
487
|
+
class Proc
|
488
|
+
def to_s
|
489
|
+
"#<%s:0x%08x>" % [ self.class, object_id]
|
210
490
|
end
|
211
491
|
end
|
212
492
|
|
213
493
|
|
214
|
-
|
215
|
-
|
216
|
-
# Alias the question marks away from all method names because
|
217
|
-
# they're a nuisance on the command line.
|
218
|
-
alias hidden hidden?
|
219
|
-
alias visible visible?
|
220
|
-
alias broken_link broken_link?
|
221
|
-
alias dir dir?
|
222
|
-
alias binary binary?
|
223
|
-
alias bin bin?
|
224
|
-
alias vimswap vimswap?
|
225
|
-
|
226
|
-
def blockdev ; blockdev? ; end
|
227
|
-
def chardev ; chardev? ; end
|
228
|
-
def directory ; directory? ; end
|
229
|
-
def executable ; executable? ; end
|
230
|
-
def executable_real ; executable_real? ; end
|
231
|
-
def file ; file? ; end
|
232
|
-
def grpowned ; grpowned? ; end
|
233
|
-
def owned ; owned? ; end
|
234
|
-
def pipe ; pipe? ; end
|
235
|
-
def readable ; readable? ; end
|
236
|
-
def readable_real ; readable_real? ; end
|
237
|
-
def setgid ; setgid? ; end
|
238
|
-
def setuid ; setuid? ; end
|
239
|
-
def socket ; socket? ; end
|
240
|
-
def sticky ; sticky? ; end
|
241
|
-
def symlink ; symlink? ; end
|
242
|
-
def writable ; writable? ; end
|
243
|
-
def writable_real ; writable_real? ; end
|
244
|
-
def zero ; zero? ; end
|
245
|
-
|
246
|
-
# convenient digest and time format methods
|
247
|
-
def method_missing sym, *args, &block
|
248
|
-
case sym.to_s
|
249
|
-
when /\Adigest_(.*)/, /\A([a-z]+[0-9]+)\z/ then
|
250
|
-
m = $1
|
251
|
-
d = begin
|
252
|
-
Digest.const_get m.upcase
|
253
|
-
rescue NameError
|
254
|
-
if m =~ /sha\d\d\d/ then m = "sha2" end
|
255
|
-
require "digest/#{m}" and retry
|
256
|
-
raise
|
257
|
-
end
|
258
|
-
e = d.new
|
259
|
-
read 0x1000_0000 do |b| e.update b end
|
260
|
-
e.hexdigest
|
261
|
-
when /\A([amc]time)!\z/ then
|
262
|
-
(send $1).strftime "%Y-%m-%d %H:%M:%S %z"
|
263
|
-
else
|
264
|
-
super
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
def hide_instance_eval
|
269
|
-
instance_eval yield
|
270
|
-
end
|
271
|
-
|
272
|
-
end
|
273
|
-
|
274
|
-
|
275
|
-
@params = {}
|
276
|
-
|
277
|
-
envopts = ENV[ "RBFIND_OPTIONS"]
|
278
|
-
$*.unshift *envopts.split if envopts
|
279
|
-
opts = GetoptLong.new *OPTIONS.map { |(long,short),arg,|
|
280
|
-
[long,short,(arg ? GetoptLong::REQUIRED_ARGUMENT : GetoptLong::NO_ARGUMENT)]
|
281
|
-
}
|
282
|
-
opts.ordering = GetoptLong::PERMUTE
|
283
|
-
opts.quiet = true
|
284
|
-
begin
|
285
|
-
opts.each do |opt,arg|
|
286
|
-
case opt
|
287
|
-
when '--help' then usage ; exit
|
288
|
-
when '--version' then puts PROGRAM ; exit
|
289
|
-
when '--examples' then usage_examples ; exit
|
290
|
-
when '--verbose' then @verbose = true
|
291
|
-
when '--show' then @show = true
|
292
|
-
when '--bw' then @color = false
|
293
|
-
when '--colored' then @color = true
|
294
|
-
when '--depth' then @params[ :depth] = true
|
295
|
-
when '--maxdepth' then @params[ :max_depth] = arg
|
296
|
-
when '--follow' then @params[ :follow] = true
|
297
|
-
when '--sort' then @params[ :sort] = arg
|
298
|
-
when '--sort-by' then
|
299
|
-
@params[ :sort] = instance_eval "proc { |name| #{arg} }"
|
300
|
-
when '--require' then require arg
|
301
|
-
when '--fileutils' then require "fileutils" ; include FileUtils
|
302
|
-
when '--puts-path' then @puts = true
|
303
|
-
when '--ls-l' then @puts = true ; @wd = 6
|
304
|
-
when '--wider' then @wd = @wd ? @wd.succ : 4
|
305
|
-
when '--slash' then @slash = true
|
306
|
-
when '--lines' then @lines = :plain ; @block = arg
|
307
|
-
when '--reallines' then @lines = :plain ; @real = true ; @block = arg
|
308
|
-
when '--grep' then @lines = :grep ; @block = arg
|
309
|
-
when '--igrep' then @lines = :grep ; @icase = true ; @block = arg
|
310
|
-
when '--binary' then @binary = true
|
311
|
-
when '--no-vcs' then @vcs = true
|
312
|
-
when '--no-swap' then @vim = true
|
313
|
-
when '--skip' then @skip = arg
|
314
|
-
when '--demand' then @demand = arg
|
315
|
-
when '--ext' then @ext = arg
|
316
|
-
when '--visible' then @visible = true
|
317
|
-
when '--nodirs' then @nodirs = true
|
318
|
-
when '--begin' then @blkbegin = arg
|
319
|
-
when '--end' then @blkend = arg
|
320
|
-
when '--file' then @block = File.read arg
|
321
|
-
when '--encoding' then e, i = arg.split ":" ; set_encoding e, i
|
322
|
-
end
|
323
|
-
end
|
324
|
-
rescue GetoptLong::InvalidOption
|
325
|
-
$stderr.puts $!
|
326
|
-
$stderr.puts
|
327
|
-
usage
|
328
|
-
exit 9
|
329
|
-
rescue
|
330
|
-
$stderr.puts $!
|
331
|
-
exit 8
|
332
|
-
end
|
333
|
-
|
334
|
-
def color_on stream
|
335
|
-
unless @color.nil? then
|
336
|
-
@color
|
337
|
-
else
|
338
|
-
!File::ALT_SEPARATOR && stream.tty?
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
if color_on $stderr then
|
343
|
-
def show_error e
|
344
|
-
$stderr.puts "\e[31m#{e.class}: \e[1m#{e}\e[m"
|
345
|
-
end
|
346
|
-
else
|
347
|
-
def show_error e
|
348
|
-
$stderr.puts "#{e.class}: #{e}"
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
def error_handle
|
353
|
-
if @verbose then
|
354
|
-
yield
|
355
|
-
else
|
356
|
-
begin
|
357
|
-
yield
|
358
|
-
rescue ArgumentError
|
359
|
-
show_error $!
|
360
|
-
if $!.message[ "invalid byte sequence"] then
|
361
|
-
$stderr.puts <<-EOT
|
362
|
-
Hint: Try to give a different default encoding by explicitly setting one or
|
363
|
-
by changing the locale.
|
364
|
-
|
365
|
-
$ rbfind -K ascii-8bit ...
|
366
|
-
$ LC_ALL="C" rbfind ...
|
367
|
-
|
368
|
-
Alternatively, you may prefer to scrub the invalid encodings yourself.
|
369
|
-
|
370
|
-
$ rbfind -P 'name.scrub =~ /Fu.ball/'
|
371
|
-
|
372
|
-
EOT
|
373
|
-
end
|
374
|
-
exit 1
|
375
|
-
rescue
|
376
|
-
show_error $!
|
377
|
-
exit 1
|
378
|
-
rescue NoMemoryError, ScriptError, SignalException
|
379
|
-
show_error $!
|
380
|
-
exit 2
|
381
|
-
end
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
|
386
|
-
error_handle do
|
387
|
-
|
388
|
-
co = color_on $stdout
|
389
|
-
opath = co ? "cpath" : "path"
|
390
|
-
@slash and opath << "!"
|
391
|
-
case @lines
|
392
|
-
when :plain then
|
393
|
-
@puts and @block = "( #@block ) and colsep #{opath}, num, line"
|
394
|
-
@real and @block = "break if ~/\0/o ; #@block"
|
395
|
-
@block = "lines { |line,num| #@block }"
|
396
|
-
|
397
|
-
when :grep then
|
398
|
-
RE = Regexp.new @block, @icase && Regexp::IGNORECASE
|
399
|
-
@block = "grep RE"
|
400
|
-
@block << ", true" if co
|
401
|
-
@block << " ; $stdout.flush" unless $stdout.tty?
|
402
|
-
@binary or @block = "not binary? and (#@block)"
|
403
|
-
|
404
|
-
else
|
405
|
-
@block ||= if $*.last and not (File.exists? $*.last) then
|
406
|
-
$*.pop.dup
|
407
|
-
else
|
408
|
-
@puts ||= true
|
409
|
-
"true"
|
410
|
-
end
|
411
|
-
if @puts then
|
412
|
-
@block = "( #@block ) and "
|
413
|
-
@block << if @wd then
|
414
|
-
"spcsep stype+modes, user|#@wd, group|#@wd, size.w#@wd, " +
|
415
|
-
"mtime.lsish, #{opath} + #{co ? 'carrow' : 'arrow'}.to_s"
|
416
|
-
else
|
417
|
-
"puts #{opath}"
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
end
|
422
|
-
|
423
|
-
if @skip then
|
424
|
-
RE_SKIP = Regexp.new @skip, File::ALT_SEPARATOR&&Regexp::IGNORECASE
|
425
|
-
@block.insert 0, "next if name =~ RE_SKIP ; "
|
426
|
-
end
|
427
|
-
|
428
|
-
if @demand then
|
429
|
-
RE_DEMAND = Regexp.new @demand, File::ALT_SEPARATOR&&Regexp::IGNORECASE
|
430
|
-
@block.insert 0, "next unless name =~ RE_DEMAND ; "
|
431
|
-
end
|
432
|
-
|
433
|
-
if @ext then
|
434
|
-
RE_EXT = Regexp.new '\A\.(' +
|
435
|
-
@ext.split(/ +|,/).map { |e| e[ /\A\.?(.*)\z/, 1] }.join('|') + ')\z',
|
436
|
-
File::ALT_SEPARATOR&&Regexp::IGNORECASE
|
437
|
-
@block.insert 0, "ext =~ RE_EXT or next ; "
|
438
|
-
end
|
439
|
-
|
440
|
-
@visible and @block.insert 0, "visible? or prune ; "
|
441
|
-
|
442
|
-
@nodirs and @block.insert 0, "next if dir? ; "
|
443
|
-
|
444
|
-
@vcs and @block.insert 0, "no_vcs ; "
|
445
|
-
@vim and @block.insert 0, "vimswap? and next ; "
|
446
|
-
|
447
|
-
args = $*.dup
|
448
|
-
if args.empty? and not $stdin.tty? then
|
449
|
-
$stdin.each_line { |l|
|
450
|
-
l.chomp!
|
451
|
-
args.push l
|
452
|
-
}
|
453
|
-
end
|
454
|
-
|
455
|
-
if @show then
|
456
|
-
class Proc
|
457
|
-
def to_s
|
458
|
-
"#<%s:0x%08x>" % [ self.class, object_id]
|
459
|
-
end
|
460
|
-
end
|
461
|
-
INDENT = " "*2
|
462
|
-
def puts_val *args
|
463
|
-
l = [ INDENT, *args].join ""
|
464
|
-
puts l
|
465
|
-
end
|
466
|
-
puts "arguments:"
|
467
|
-
args.each { |a| puts_val a }.any? or puts_val "(none)"
|
468
|
-
puts "parameters:"
|
469
|
-
@params.each { |k,v| puts_val k, "=", v }.any? or puts_val "(none)"
|
470
|
-
puts "block:"
|
471
|
-
self.class.constants.grep( /^RE(_[A-Z]+)?$/).each { |re|
|
472
|
-
v = self.class.const_get re
|
473
|
-
puts_val re, "=", v
|
474
|
-
}
|
475
|
-
puts_val @block
|
476
|
-
exit
|
477
|
-
end
|
478
|
-
|
479
|
-
@params[ :error] = proc do
|
480
|
-
case $!
|
481
|
-
when Errno::EPIPE then raise
|
482
|
-
when NameError, TypeError then raise
|
483
|
-
when ArgumentError then raise
|
484
|
-
else show_error $!
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
@block = <<-EOT
|
489
|
-
handle_error do
|
490
|
-
#@block
|
491
|
-
end
|
492
|
-
EOT
|
493
|
-
|
494
|
-
eval @blkbegin if @blkbegin
|
495
|
-
RbFindApp.open args, @params do |f| f.hide_instance_eval { @block } end
|
496
|
-
eval @blkend if @blkend
|
497
|
-
end
|
494
|
+
RbFind::Application.new.run
|
498
495
|
|