6 个版本
使用旧的 Rust 2015
0.1.5 | 2018 年 5 月 6 日 |
---|---|
0.1.4 | 2018 年 4 月 22 日 |
#1 in #ignore-case
23KB
406 行
findr - 无标志的查找文件
我对 Unix find
命令提供的功能数量印象深刻,但仍然无法记住如何使用它进行除基本功能之外的操作;否则我会去谷歌搜索。我对标志的记忆不是很好,但我确实记得 表达式。 findr
只接受两个参数;基本目录和一个 过滤表达式
$ findr . 'path.ext=="rs" && path.size > 1kb'
$ findr . 'path.is_file && date.before("1 jan")'
$ findr . 'path.ext=="md" and date.after("last tuesday")'
过滤表达式传递了 path
、date
和 mode
,由于功能强大的小嵌入式语言 rhai,因此支持相当任意的表达式。作为一个小便利,"and"、"or" 和 "not" 被理解,因为这些在匆忙中更容易输入。
path
具有以下字段
is_file
这个路径是文件吗?is_dir
这个路径是目录吗?is_exec
这个文件可执行吗?is_write
这个路径可写吗?size
文件条目的字节数ext
文件路径的扩展名file_name
路径的文件名部分
还有一个 matches
方法(例如 path.matches("*/readme.*")
),以及一个不区分大小写的 ASCII 对应版本 matches_ignore_case
。
date
具有以下方法
before(datestr)
所有在此日期之前修改的文件after(datestr)
所有在此日期之后修改的文件between(datestr,datestr)
所有在这两个日期之间修改的文件on(datestr)
所有在此天修改的文件
mode
只是通常的 Unix 权限位 - 表达式可以包含 Rust 表示法中的八进制常量(例如 0o755
)
数字可以有一个大小前缀(kb、mb、gb - 不区分大小写)并且日期字符串由 chrono-english 解释。
目前,findr
会忽略由.gitignore
排除的隐藏目录和文件。没有使用标志的情况下,这并不完全可能!
~$ findr -h
findr: find files and filter with expressions
-n, --no-hidden look at hidden files and follow hidden dirs
-g, --no-gitignore do not respect .gitignore
-f, --follow-links follow symbolic links
-i, --case-insensitive do case-insensitive glob matches
-m, --manual show more detailed help about findr
<base-dir> (path) base directory to start traversal
<filter-function> (default 'true') filter paths
默认情况下,它使用英式英语日期(即不是“9/11”),除非定义了环境变量FINDR_US
。
尊重.gitignore
可以让你的生活更轻松,如果你对构建工件不感兴趣。在Rust项目中特别有用,因为增量编译会产生大量的中间构建工件。(如果你确实需要覆盖默认设置,则-gn
将完成这项工作。)
有了findr
,我现在终于可以回答“我在星期二都做了些什么?”这个问题了。
~$ findr . 'date.on("last tues")'
./rust/repos/findr/src/errors.rs
./rust/scratch
./rust/scratch/over/test.over
./rust/scratch/over/type1.over
./rust/scratch/over/over.rs
./rust/scratch/over/empty.over
./rust/scratch/over/tuple.over
./rust/scratch/over/strs.over
./rust/scratch/over/main.over
./rust/scratch/over/id.over
./rust/scratch/over/numbers.over
./rust/scratch/over/strings.over
./rust/scratch/over/map.over
./rust/scratch/over/str.over
./rust/scanlex/src
./rust/scanlex/src/lib.rs
使用-g
标志(忽略.gitignore
),那天有538个文件被更改!
为了说明我的关于标志狂热的观点,findr . 'path.ext="rs"'
的精确等价物是
find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*.rs' -print
(我不得不查一下)
快捷过滤器
受ripgrep
默认值启发的功能是快捷过滤器。
引用--manual
If a filter is not provided and the base is not a dir, then
it is interpreted as a glob pattern searching from current dir.
If the glob does not start with '*', then:
* file-pattern becomes */file-pattern
* .ext becomes *.ext
也就是说,findr readme.md
相当于findr . 'path.matches("*/readme.md")
,而findr .c
相当于findr . 'path.matches("*.c")
。
--case-insensitive
(-i
)标志将发出matches_ignore_case
而不是matches
,因此findr -'readme.*'
将匹配README.TXT
、README.md
或野外发现的任何许多变体。
此外,我们允许在这个隐含的通配符模式之后添加一个额外的条件。如果是<
或>
,那么它的意义是路径大小表达式,否则是时间表达式。
因此,findr '.c after last tues'
将给我所有在最后一个星期二之后修改的C源文件,而findr '.doc > 256Kb'
将给出所有大于256Kb的.doc文件。(单引号仍然很重要,以保护我们的表达式不受shell通配符扩展的影响。)
要查看findr
对其过滤器所做的转换,设置环境变量FINDR_DEBUG
。
依赖关系
~9–17MB
~217K SLoC