1 个不稳定版本

0.1.0 2021年5月19日

#22#pattern-match

MIT 许可证

135KB
3.5K SLoC

Nym

Nym 是一个跨平台库和命令行界面,用于使用模式操作文件。它受 mmv 启发,并非常松散地基于它。

GitHub docs.rs crates.io

用法

Nym 命令由标志、选项和模式组成。大多数命令都是由源模式到匹配源文件的转换模式和目标路径的转换模式组成的转换。转换包括 appendcopylinkmove 命令。一些命令,如 find,仅使用源模式。

写入文件系统(即,像 copy 这样的转换)的命令默认是交互式的,并打印一个清单,然后提示继续写入。可以通过 --interactive 选项控制此行为。

Nym 仅在文件上操作(除了 --parent/-p 标志,它会在目标路径中创建父目录,这些路径是从目标模式派生出来的)。命令永远不会应用于目录。例如,无法复制、链接或移动目录。

以下命令将工作目录树中的所有文件复制到相邻文件中,并附加 .bak 扩展名。

nym copy '**' '{#0}.bak'

在这里,copy 是子命令(也称为执行器),** 是源模式,{#0}.bak 是目标模式。请注意,在大多数shell中,模式必须转义以避免与shell功能(如扩展)交互。引号模式通常可以防止这些不希望交互。

以下命令查找 src 目录下所有扩展名为 .go.rs 的文件。

nym find '**/src/**/*.{go,rs}'

源模式

源模式使用类似 Unix 的 glob 来匹配要执行的动作的源文件。这些 glob 类似于字面路径,但还支持通配符、字符类和可以与文件系统上的路径匹配的替代项。匹配提供捕获文本,可以在目标模式中使用。

路径分隔符是Globs的一个观点。正斜杠 / 始终是路径分隔符,反斜杠 \ 是禁止的(反斜杠用于转义序列,但字面序列 \\ 不受支持)。分隔符在各个平台之间都是规范的;例如,glob模式可以在Windows上匹配路径。

通配符

通配符匹配路径中的一些任意文本,是glob提供的最基本工具。

树形通配符 ** 匹配零个或多个子目录。 这是匹配任意目录的唯一方式;所有其他通配符都不跨目录边界匹配。当一个树形通配符参与匹配且不终止模式时,其捕获包括一个尾随路径分隔符。如果一个树形通配符不参与匹配,其捕获是一个空字符串,没有路径分隔符。树形通配符必须由路径分隔符或终止符(例如glob或子glob的开始和/或结束)限定。如果一个glob仅由树形通配符组成,则它匹配工作目录树中的所有文件。

零个或多个通配符 *$ 匹配零个或多个任何字符 除了路径分隔符。零个或多个通配符不能与其他零个或多个通配符相邻。通配符 * 是贪婪的,会匹配尽可能长的文本,而通配符 $ 是懒惰的,会匹配尽可能短的文本。当跟随着一个字面量时,通配符 * 会匹配到该字面量的最后一个出现,而通配符 $ 会匹配到该字面量的第一个出现。

精确匹配单个字符的通配符 ? 匹配任何单个字符 除了路径分隔符。精确匹配通配符不会自动分组,所以连续的通配符模式(如 ???)会为每个 ? 通配符形成独立的捕获。可以使用替代方法将精确匹配通配符组合成一个捕获,例如 {???}(见下文)。

字符类

字符类匹配任何单个字符,来自一组字面量和范围 除了路径分隔符。类由方括号 [...] 限定。单个字符字面量按原样指定,例如 [ab] 匹配 ab。字符范围由两个字符组成,中间用连字符分隔,例如 [x-z] 匹配 xyz

可以在单个字符类中使用任意数量的字符字面量和范围。例如,[qa-cX-Z] 匹配 qabcXYZ 中的任何一个。

字符类可以通过在类模式开头包含一个感叹号 ! 来进行否定。例如,[!a] 匹配除 a 之外的任何字符。

请注意,字符类也可以用于转义元字符,如 *$ 等,尽管 glob 也支持通过反斜杠 \ 进行转义。要在字符类内匹配控制字符 []-,它们必须通过反斜杠进行转义,例如 [a\-] 以匹配 a-

备选方案

备选方案匹配由花括号 {...,...} 定义的逗号分隔的子 glob 的任意序列。例如,{a?c,x?z,foo} 依次匹配任何子 glob a?cx?zfoo。备选方案可以任意嵌套,例如在 a{b,c{d,e{f,g}}} 中。

备选方案形成一个单独的捕获组,无论其子 glob 的内容如何。此捕获由子 glob 的完整匹配形成,因此如果子 glob a?c{a?c,x?z} 中匹配 abc,则捕获文本将是 abc不是 b,因为它会在备选序列之外)。备选方案可以用于使用单个子 glob 对捕获文本进行分组,例如 {*.{go,rs}} 以捕获具有特定扩展名的整个文件名或 {??} 以分组恰好一个通配符的序列。

子 glob,特别是包含通配符的子 glob,必须考虑相邻的模式。例如,不可能引入一个仅与路径分隔符或终止符相邻的树形通配符,因此 foo{bar,baz/**} 是允许的,但 foo{bar,**/baz} 是不允许的。因为匹配任何内容,所以单个树形通配符在子 glob 中**永远**不允许,因此 foo/{bar,**} 是不允许的。

文字和平台特定功能

无法识别的组件被视为字面量。结合对路径分隔符的严格解释,这意味着某些平台特定的功能不能作为from模式的组成部分。

特别是,虽然from模式可以有根路径,但不能包含方案或Windows路径前缀。在Windows上,可以通过--tree/-C选项使用UNC路径或其他带有前缀的路径,该选项使用本地路径设置from模式应用的目录。例如,以下命令从UNC共享路径\\server\share\src复制所有文件。

nym copy -p --tree=\\server\share 'src/**' 'C:\\backup\\{#1}'

Glob不支持父目录的概念。然而,任何不变(字面量)前缀都会被平台重新解释为本地路径,因此以..开始的from模式在Unix和Windows上会按预期行为。例如,以下命令直观地操作在当前工作目录的父目录中。

nym find '../src/*.rs'

然而,..被视为字面量,当它跟在glob的变体(非字面量)组件后面时,它只匹配具有字面量组件..的路径。在遍历目录树时这种情况不会发生,因此,跟随变体模式(如通配符)的字面量..匹配不到任何内容,不应使用。例如,from模式src/**/../*.rs永远不会产生匹配的文件。

目标模式

目标模式解析目标路径。这些模式由字面量和替换组成。替换可以是来自相应from模式的捕获或读取文件元数据的属性。替换由大括号{...}分隔。字面量按原样形成本地路径。

捕获

捕获使用哈希和索引来索引from模式,例如{#1}。这些索引从1开始计数;0索引用于匹配的全文。空大括号也表示匹配的全文,所以{#0}{}是等效的。

捕获可能包含一个条件。条件指定基于匹配文本是否为空来替换文本。条件遵循捕获标识符使用类似三元运算符的语法:它们以一个问号?开始,后跟非空情况,一个冒号:,最后是空情况。每个情况都支持字面量,字面量由方括号[...]分隔。在非空情况下,可以使用两个用逗号分隔的字面量来代替周围的前缀和后缀。条件情况和替换文本可能为空。

例如,{#1?[],[-]:} 被替换为第一个捕获的匹配文本,当该文本非空时,后面跟着后缀 -。当 {#1?:[unknown]} 的匹配文本为空时,将被替换为文字 unknown

属性

属性包括源文件的元数据,在目标路径中指定,并使用感叹号 ! 后跟名称进行指定。属性名称不区分大小写。支持的属性在以下表中描述。

模式 元数据 类型 / 格式 Cargo 功能
{!b3sum} BLAKE3 哈希摘要 摘要 property-b3sum(默认)
{!ctime} 创建时间戳 日期时间 n/a
{!md5sum} MD5 哈希摘要 摘要 property-md5sum(默认)
{!mtime} 修改时间戳 日期时间 n/a

例如,{!b3sum} 被替换为匹配文件的 BLAKE3 哈希摘要。

属性与一个数据类型及其相应的格式相关联,并将它们转换成替换的输出文本。格式可选,位于属性名称后的冒号 : 之后,并用方括号 [...] 分隔。例如,日期时间数据类型使用类似于 strftime 的格式,并且模式 {!mtime:[%Y]} 输出源文件修改时间戳的四位年份文本。

属性可能需要额外的依赖项,并且在构建过程中可以使用 Cargo 功能 来切换一些属性。

文本格式化工具

替换(包括捕获和属性)支持可选的文本格式化工具。文本格式化工具必须在替换中最后出现,位于一个垂直线 | 之后。可以使用任意数量的文本格式化工具,它们由逗号 , 分隔,并且按照它们出现的顺序从左到右应用。

文本格式化工具与属性格式不同,正如其名称所暗示的,它们仅在替换的输出文本上操作(它们不操作非文本数据)。

填充格式化程序使用指定的字符填充替换文本到指定的宽度和对齐方式。例如,{#1|>4[0]} 使用右对齐和填充字符 0 将替换文本填充到四列。如果原始替换文本是 13,则在此示例中格式化后变为 0013。左对齐和居中对齐也通过 <^ 分别支持。

有三种大小写格式化程序:小写、大写和标题大小写,分别对应大小写不敏感的模式 loweruppertitle。这些格式化程序不接受参数,并更改支持字符的大小写。请注意,title 对单词分隔敏感,只发生在空格和连字符 -(并且 不是 下划线 _,例如)之间。

合并格式化程序将匹配的输入字符替换为输出字符。例如,{#1|%[_-][~]} 将任何 _- 的实例替换为波浪号 ~

文本格式化程序可以组合起来执行复杂格式化。例如,以下命令提取由下划线 _ 分隔的文件名的一部分,并使用带空格的标题大小写格式化该部分。

nym move '$_$_*.mp4' '{#2|%[-][ ],title}.mp4'

给定一个名为 the-show-title_the-episode-title_the-encoding.mp4 的文件,上述转换将将其移动到 The Episode Title.mp4

箱子

Nym 的核心功能作为独立的库公开,前端在此库之上开发。以下表格描述了在 Nym 存储库 中维护的官方 Rust 箱子。

箱子 描述
nym 实现 Nym 核心功能的库。
nym-cli nym 命令行界面 (CLI) 的二进制文件。

这些箱子的主版本和次要版本一起升级。

安装

以下将介绍多种方式安装 nym 二进制文件。

存储库

要从存储库的克隆中安装 nym,首先安装 Rust,然后使用 cargo 构建并安装 nym

git clone https://github.com/olson-sean-k/nym.git
cd nym/nym-cli
cargo install --locked --path=. --force

默认情况下,这将构建 master 分支,它通常跟踪测试中的即将到来的更改。要安装特定版本,请在使用 cargo install 之前检出版本标签。请注意,不同版本之间的构建说明可能不同;请参阅克隆中的 README

git checkout v0.0.0

注册表

要从crates.io Rust 包注册表安装 nym 的版本,请先安装 Rust,然后使用 cargo 构建并安装 nym

cargo install nym-cli --locked --force

要安装特定版本,请使用 --version 选项。

cargo install nym-cli --version=0.0.0 --locked --force

软件包

以下表格描述了可以用来安装 nym 的软件包。

平台 软件包
架构 (AUR) nym-git

免责声明

Nym 提供原样,不提供任何保证。在编写本文时,Nym 是实验性的,可能存在错误。可能发生数据丢失。请自行承担风险。

依赖项

~10–21MB
~299K SLoC