#file #find #file-search #grep #tool #find-files #replace

bin+lib findfile

一种便捷的文件搜索方式

9 个版本

0.2.8 2023 年 6 月 27 日
0.2.7 2023 年 6 月 26 日

#608文件系统

Download history 22/week @ 2024-03-10 58/week @ 2024-03-31

54 每月下载量

MIT/Apache

100KB
2.5K SLoC

FindFile (FF)

一个简单、便捷且强大的 find 替代品。

注意:此存储库处于积极开发中

语法(大部分)已经确定,但语法的内部实现需要大量工作。

路线图

  • 基本词法分析器
    • 字符串字面量(带有插值):"..."
    • Perl 正则表达式字面量(带有插值):$/.../
    • 路径字面量(有点像带有插值):foo/*.txt
    • 文件大小字面量:12kb4.9mib
    • $env 变量和 $1 命令行变量
    • 日期和时间字面量
    • 在路径字面量中,+ 的位置从搜索根开始,而不是总是从当前工作目录根开始。
  • 基本抽象语法树 (AST) 构建器
    • 数学和逻辑二元运算符(大多数在运行时不工作)
    • 代码块
    • 基本赋值
    • -Xk+Xk 需要实现较大和较小的功能
    • 复合赋值
    • 逻辑赋值
    • 数组与哈希表(它们将是相同的类型)
    • 函数调用
    • 函数声明
  • 基本运行时
    • 确定起始位置(大部分工作)
    • 为大多数类型添加基本数学
    • 清理变量访问方式
    • 支持 ^{}${} 以用于开始和结束块
    • 一种在不同类型之间转换的方法
    • 添加更多支持的功能
      • 完善此文件中已有的功能
      • 添加 depth 和 "目录中的子项数量"
    • 将其转换为虚拟机
      • 添加 JIT
  • 参数解析器
    • 大多数参数(目前实现和待办事项)都已添加
    • 打印出匹配行及其文件内容(类似于 ripgrep)
    • 进行美化,使其看起来非常漂亮(clap 大多数时候都能做得很好)
  • 杂项
    • 优化文件读取,避免读取整个文件来匹配第一行
    • 清理类型表示
    • 可能需要从文件大小中移除重要位?
    • 明确我在使用 Vec<u8>OsStringString 时的差异。
    • 找出如何协调 ${} 用于开始块和 ${} 用于环境变量
    • 未知变量应该警告吗?

以下是我最终希望支持的示例

  • 列出目录中的所有文件: ff 'isfile && depth=1'
  • 制作文件及其目录的 "树":ff -n 'print "\t"*depth_from(start), basename'
  • 查找至少1GB或10天前更新的所有文件:ff 'size > 1g || modify > -10d'
  • 将后缀 -YYYY-MM-DD 添加到所有文件,但保留扩展名:ff -n 'isfile && mv(file, "{dir}{base}-{ymd_date}.{suffix})'
  • 查找所属文件夹为 log 且10天内的所有文件:ff 'isfile && modify > -10d && basename(parent) = "log"'
  • 查找包含 "hello" 和 "world" 的所有文件,可能位于不同的行:ff 'contents =~ /hello/ && contents =~ /world/'
  • 通过直接文件大小查找最大的文件夹:(${} 在脚本结束时运行):ff -n '${print maxdir} dirsize > dirsize(maxdir) then maxdir=dirsize'

关键词

  • true 等同于 1
  • false 等同于 0

if else while continue break def return skip/next

函数

如果一个函数不接受任何参数,你可以省略括号。例如,file?file?() 相同,因为 file?() 等同于 file?(path)

查询信息

名称和参数 别名 功能描述
文件?(p=路径) f? 返回 p 是否是文件。
目录?(p=路径) d? dir? 返回 p 是否是目录。
可执行文件?(p=路径) e? exe? 返回 p 是否是可执行文件。
符号链接?(p=路径) s? sym? 返回 p 是否是符号链接。
二进制文件?(p=路径) b? bin? 返回 p 是否是二进制文件。
gitignore?(p=路径) gi? 返回 p 是否被 gitignore 文件忽略。
隐藏?(p=路径) gi? 返回 p 是否以 . 开头。
ok?(msg) 打印 msg,然后请求确认。
macos(...) 未来想法:类似 macos 标签等功能

| root() | r | 开始查看的根目录 | | path() | p | 当前路径 | | dirname(p=path) | d dir parent | 父目录 | | extname(p=path) | e ext extension | 扩展名,如果有,不包含 . | | extnamed(p=path) | ed extd extensiond | 扩展名,如果有,包含 . | | basename(p=path) | b bn base | 除 p 的父目录之外的所有内容 | | stemname(p=path) | s stem | basename,如果没有扩展名(如果有) |

杂项

| print(...) | pr | 打印其参数(之间没有空格),后跟换行符 | | printn(...) | prn | 打印其参数(之间没有空格),不跟换行符 | | next | skip | 忽略当前参数并继续 | | exit(status) | quit | 停止整个脚本 | | pwd() | 当前工作目录 | | depth(src=path, dst=root) | 从 dst 出发,有多少个目录层级。 | | date(<...>) | 当前日期,格式化为时间 | | sleep(<...>) | 睡眠 |

可执行函数

这些函数中的一些是“破坏性的”(例如 mv):如果破坏性文件会覆盖另一个文件,它将检查命令行参数以确定如何操作(--interactive 表示总是询问,--force 表示永不询问;如果两者都没有给出,则默认为 --force)。您可以使用 <fn>i 总是进行交互式操作或使用 <fn>f 总是强制执行(类似于 mvf)。

所有这些都必须用括号调用(可能是?)

名称和参数 功能描述
exec(...) ..
mv{,f,i}(src=路径,dst) src 移动到 dst;仅在交互式时确认是否覆盖文件
rm{,f,i}(src=路径) 删除位于 src 的文件;在交互式时始终确认。如果给出空目录,rm 的行为类似于 rmdir
rmr{,f,i}(src=路径) 递归删除位于 src 的文件;在交互式时始终确认
cp{,f,i}(src=路径,dst) src 复制到 dst;仅在交互式时确认是否覆盖文件
ln...
mkdir(p) p 处创建一个目录;它还会创建所有父目录。
touch(src=路径) p 处创建一个目录;它还会创建所有父目录。

IDEAS

移动文件时出现问题。您想做什么:(Q)uit:停止整个程序,(C)ontinue:继续进行,(R)etry:再次尝试(可能是在您修复某些内容之后),(S)hell:进入一个shell,其中 $cpath 是当前路径的变量

依赖项

~6–17MB
~219K SLoC