Skip to main content

根据用户定义的模式自动重命名和排序标记文件(例如由 TagSpaces 生成的文件)的实用程序。

项目描述

自我标记的

autotagical是一种根据用户定义的模式自动重命名和排序标记文件(例如由TagSpaces生成的文件)的实用程序。它从多个输入目录之一读取标记文件,然后根据用户提供的模式中指定的规则重命名和/或将它们移动到输出文件夹层次结构。它旨在与文件标记软件一起使用,例如 TagSpaces

入门/安装

通过运行以下命令可以最容易地使用pip安装autotagical

pip install autotagical

如果您想通过克隆此存储库来运行自动标记,那么您需要安装以下要求,例如使用pip

  • setuptools
  • jsonschema>=3
  • packaging

使用自动标记

用法

autotagical [-h] [-V] [-C <config file>] [-H] [-i <input path>]
            [-I <ignore file>] [-R] [-o <output path>] [-O]
            [-g <tag group file>] [-s <schema file>] [-A] [--cleanin]
            [--cleanout] [-c] [-F] [-k] [-m] [-M] [-n] [-N] [-t]
            [--debug] [-l <log file>] [-L] [-P] [-q] [-v] [--force]
            [--yes]

帮助选项

这些选项显示有用的信息并退出。

  • [-h/--help]-- 显示帮助/使用信息并退出。
  • [-V/--version]-- 显示当前版本和已知文件格式信息并退出。

配置选项

  • [-C/--config <config file>]-- 在指定路径加载配置文件。

输入选项

这些选项确定要移动和/或重命名的文件中的行为加载。必须至少指定一个输入文件夹。

  • [-H/--hidden]-- 处理隐藏文件(和目录,如果指定了 -R)。
  • [-i/--input <input folder>]-- 带有输入文件的文件夹的路径。可以多次指定。
  • [-I/--ignore <ignore file>]-- 要忽略的文件模式(正则表达式格式)的路径(每个都在新行上)。可以多次指定。
  • [-R/--recursive]-- 从输入文件夹递归加载文件,即下降到子文件夹。

输出选项

这些选项确定输出移动/重命名文件的行为(但不指定移动和/或重命名文件的规则)。必须至少指定一个输出文件夹(通过一个选项或另一个)。

  • [-o/--output]-- 输出文件的根文件夹的路径。可以多次指定(输出将被复制到每个)。
  • [-O/--organize]-- 就地组织文件(即使用第一个输入文件夹进行输出)。通常与 -R 一起使用。

架构选项

这些选项指定移动/重命名文件的规则,是 autotagical的核心。有关这些文件结构的信息可以在下面的标记组格式模式格式部分中找到。

  • [-g/--groups <tag group file>]-- 要从中读取标签组的文件的路径。可以多次指定(组将被合并)。文件可以是TagSpacesautotagical格式。
  • [-s/--schema <schema file>]-- 用于移动/重命名文件的模式文件的路径。可以多次指定,在这种情况下,在指定的订单文件中优先考虑规则。

功能选项

这些选项调整自动标记的默认功能,如下所示,通常调整各种情况的处理方式。

  • [-A/--allmatchroot]-- 使输出文件夹的根目录匹配所有标签,即每个文件都将被移动到输出文件夹,即使它没有更具体地匹配任何地方。使用此选项是不好的做法(请考虑将/*|运算符用作根过滤器),但它是为了方便用户而提供的。该选项并不意味着-M即无法重命名的文件不会因为-A设置而被移动到根文件夹。
  • [--cleanin]-- 清理(删除)输入文件夹中的所有空文件夹。这递归,无论-R标志是否设置。
  • [--cleanout]-- 清理(删除)输出文件夹中的所有空文件夹。这递归,无论-R标志是否设置。
  • [-c/--clean]-- 清理(删除)输入和输出文件夹中的所有空文件夹。
  • [-F/--failforcerename]-- 此选项标记未能重命名由于该-N选项而被强制重命名的手动命名文件应视为文件命名失败。这听起来很复杂,但请考虑以下情况:
    • [-F]-- 正常行为(选项将被忽略)。
    • [-N]-- 强制重命名手动命名的文件,但手动命名“足够好”,无法重命名的手动命名文件将被移动。
    • [-F -N]-- 强制重命名手动命名的文件并将失败视为失败。无法重命名的手动命名文件将不会被移动。
    • [-N -M]-- 强制重命名手动命名的文件。所有文件都将被移动。
    • [-F -N -M]——相当于-N -M-F没有效果。
  • [-k/--keep]-- 保持输入文件夹中的原始文件不受影响,即将文件复制到新的目的地而不是移动它们。
  • [-m/--move]-- 仅将文件移动到目录结构中,不要尝试重命名它们。
  • [-M/--moveall]- 移动所有文件,不仅是手动命名/成功重命名的文件。
  • [-n/--name]-- 只重命名文件,不要试图将它们移动到任何目录结构中。所有文件都将放在输出文件夹的根目录中。
  • [-N/--renamemanual]-- 强制尝试重命名手动命名的文件,而不仅仅是未命名的文件。
  • [-t/--trial] - 试运行。不要实际移动或重命名文件,只需记录会发生的事情。结合-v在实时运行之前检查输出。 使用这是一种很好的做法,尤其是在对架构或选项进行任何更改之后。该-t选项确保不会将任何更改反映到磁盘上。

日志记录选项

这些选项调整运行自动标记时显示的消息类型以及是保存它们还是仅将它们打印到控制台)。

  • [--debug]-- 绝对显示一切。你可能永远不应该使用它。
  • [-l/--log <log file>]-- 将消息输出到指定文件而不仅仅是控制台。默认情况下,消息将附加到文件的末尾。
  • [-L/--overwritelog]-- 覆盖指定的日志文件,而不是追加到它。没有 没有效果-l
  • [-P/--posix]-- 特定于 Windows 的静音警告。当文件永远不会与 Windows 系统一起使用时才使用此选项(Windows 系统对文件名可以包含的内容更为挑剔)。
  • [-q/--quiet]-- 静音所有警告,只显示实际错误。不建议使用它,因为通常打印警告是有充分理由的。
  • [-v/--verbose]-- 打印所有采取的行动。这将列出每个文件移动/重命名,而不仅仅是警告失败。-t与在真正运行之前检查模式是否正在做人们想做的事情结合使用时最有用。

不安全的选项

除非您有充分的理由,否则不要使用这些。 可能会发生数据丢失。

  • [--force]-- 强制移动/重命名文件,即使有文件或目录挡道。 这将破坏文件;使用风险自负,因为可能会发生数据丢失。
  • [--yes]-- 假设所有用户提示为“是”。这意味着--force并将 破坏文件和目录。 使用风险自负,因为可能会发生数据丢失。

设置优先级

autotagical将始终优先使用按以下顺序指定的设置,从最高到最低,每个设置都会覆盖来自较低优先级来源的任何设置。请注意,只会加载一个配置文件(优先级第一个)。

  1. 命令行参数。
  2. 配置文件(首先从下面找到)。
  3. -C/--config使用参数加载的配置文件。
  4. .autotagrc输出文件夹中的文件(使用包含一个的第一个文件夹)。
  5. .autotagrc输入文件夹中的文件(使用包含一个的第一个文件夹)。
  6. .autotagrcautotagical模块文件夹中的文件。

配置文件格式

.autotagrc(或通过命令行指定的任何配置文件)应具有与任何命令行参数相同的格式,否则会希望传递。 配置文件中的不安全选项将被忽略,即如果在配置文件中设置--force--yes 则不会产生任何影响。这是为了防止在没有明确用户输入的情况下丢失数据。空格和换行符被忽略,例如有人可能会写:

-H

  -P

在配置文件中处理隐藏和忽略特定于 Windows 的警告。

标签组格式

autotagical能够读取通过从TagSpaces导出标签组生成的 JSON 文件。或者,标签组可以在 JSON 中以更简单、更易读的方式定义。这种自动标记标签组格式支持TagSpaces格式中不可用的附加功能,详情如下。

{
  "file_type": "autotagical_tag_groups",
  "tag_group_file_version": "1.1",
  "tag_groups": [
    {
      "name": "tag group 1",
      "tags": ["tag1", "tag2"...]
    },
    {
      "name": "tag group 2",
      "tags": ["tag3", "/G|tag group 1", "/RE|regex 1",...]
    },
  ]
}

遗产

自动标记格式中,标签组支持简单继承,其中子标签组可以根据一个或多个父标签组(以及任何附加标签)来定义。/G|通过在组的tags属性中为组名添加前缀来指示继承。在这种情况下,子组将继承任何父组中的所有标签。这对于简单来说很有用;它确保只需要手动定义最“叶子”标签组,同时仍然基于更广泛的组编写过滤器,如果更新更精细的组,所有这些都会更新。考虑以下简单用例:

{
    "file_type": "autotagical_tag_groups",
    "tag_group_file_version": "1.1",
    "tag_groups": [
        {
            "name": "American Styles",
            "tags": [
                "ipa",
                "dipa",
                "pale_ale"
            ]
        },
        {
            "name": "Belgian Styles",
            "tags": [
                "witbier",
                "dubbel",
                "tripel"
            ]
        },
        {
            "name": "Beer",
            "tags": [
                "/G|American Styles",
                "/G|Belgian Styles"
            ]
        }
    ]
}

在这里,我们已经根据and 定义了Beer组,而不是必须指定应该属于它的所有 6 个标签。这不仅可以更快地编写,而且可以防止在以后决定添加标签时出现疏忽错误。例如,如果将 其添加到组中,它将成为组的一部分,而无需记住手动将其添加到两个位置。虽然这个简单的案例在没有继承的情况下似乎并没有那么难以管理,但是必须添加重复标签的位置数量可能会随着标签组的多个级别迅速失控。American StylesBelgian StylesquadrupelBelgian StylesBeer

请记住以下有关继承的详细信息:

  • 多重继承——标签组可以从多个父组继承(如示例所示)。
  • 多级继承——标签组支持多级继承,即一个Alcohol组可能继承自Beer哪个继承自 American Styles
  • (缺少)菱形问题 ——由于在标签组继承中没有覆盖,菱形问题(祖父母通过两条不同的路线继承)可以毫无问题地处理。
  • 循环继承——两个组可以相互继承(无论是否通过中介)。每个继承路径将仅被遵循一次,即,如果指示标签组从其自身继承,则标签组将停止“遵循”继承路径。
  • 灵活的排序——标签组继承在定义组的顺序上是灵活的。标记组不需要位于它继承的组之后。事实上,标签组可以从完全不同的标签组文件中的组继承,无论它们的加载顺序如何(只要它们都被加载)。

正则表达式标记组

自动标记标记组格式支持根据正则表达式定义标记组。在某些情况下,这可能非常强大。例如,考虑带标签的银行对账单。不必手动将每个帐号标签添加到“帐号”组,而是可以定义一个标签组,如下所示:

{
    "name": "Account Number",
    "tags": ["/RE|(?:xx|\\*\\*)[0-9]{4}"]
}

这将使表单的任何标签**1234xx1234匹配“帐号”标签组。如果使用标准化形式处理大量标签,这可能非常有价值,尤其是在它们经常更改的情况下。

请记住有关正则表达式标记组的以下详细信息:

  • 完全匹配——正则表达式与标签名称一起使用,re.fullmatch()因此必须匹配 100% 的标签名称。
  • 继承——正则表达式将与组中的任何其他标签一样被继承。
  • 混合和匹配——标签组可以根据继承、普通标签或正则表达式的任意组合来定义。它们不需要仅根据正则表达式来指定。
  • 组内标记 (/?TIG|) 运算符-- 正则表达式标记组与组格式字符串运算符中的标记一起正常工作。将为其返回与正则表达式匹配的第一个标签。

模式格式

模式在 JSON 中以人类可读的方式定义,并且应该由单个对象组成,如下所示:

{
  "file_type": "autotagical_schema",
  "schema_file_version": "1.1",
  "tag_formats": [],
  "unnamed_patterns": [],
  "renaming_schemas": [],
  "movement_schema": []
}

这四个键中的每一个都应分配给一个数组,其结构将在以下部分中描述。

标签格式

"tag_formats": [
  {
    "tag_pattern": "Regex containing groups: file, raw_tags, tags, and extension.",
    "tag_split_pattern": "Regex to split tags with"
  },
  ...
]

各种模式必须是有效的 Python 正则表达式。"tag_pattern" 将与整个文件名一起使用re.fullmatch()并且应该匹配整个文件名并包含以下命名组:

  • file-- 匹配原始文件名(没有标签和扩展名)。
  • raw_tags-- 匹配要保留的全部标签数据,包括任何分隔符/分界字符。
  • tags-- 仅匹配标签本身和任何分隔字符。
  • extension-- 匹配文件扩展名(如果有)。

"tag_split_pattern" 应该匹配分隔各个标签的任何分隔符,并将与re.split(). 下面提供了一个示例,它与 TagSpaces使用的标签格式匹配:

"tag_formats": [
  {
    "tag_pattern": "(?P<file>.+)(?P<raw_tags>\\[(?P<tags>.+?)\\])(?P<extension>.*?)",
    "tag_split_pattern": "\\s+"
  }
]

tag_formats 可以在单个数组中提供多于一组这样的模式,从而允许自动标记在一次运行中处理以多种格式标记的文件。

未命名模式

"unnamed_patterns": [
  "regex pattern 1",
  "regex pattern 2",
  ...
]

各种模式必须是有效的 Python 正则表达式。每个都将与这些文件的文件名(更少的标签)一起使用, re.match()并且应该匹配这些文件的文件名(较少的标签),这些文件被视为需要重命名。它们将与上面使用“tag_pattern”产生的fileextension组的串联进行匹配,因此不要尝试与这两个组未捕获的任何内容进行匹配。下面提供了一个示例,它可能将 PDF 文件与两个不同扫描仪生成的时间戳相匹配:

"unnamed_patterns": [
  "[0-9]{4}_[0-9]{2}_[0-9]{2}_[0-9]{2}_[0-9]{2}_[0-9]{2}\\s*.pdf",
  "(Pages\\sfrom)?\\s*XScan_[0-9]{14}\\s*.pdf"
]

重命名模式

"renaming_schemas": [
  {
    "filter": ["condition 1", "condition 2", ...],
    "format_string": "file name format string"
  },
  ...
]

“renaming_schemas”只是一个过滤器列表,并解释了如何命名与其中任何一个匹配的文件。这个列表是有序的,文件将根据它们匹配的第一个重命名,例如,如果一个文件具有tag1andtag2 并且数组中的第一个过滤器匹配tag2第二个tag1,则文件将根据 重命名tag2。这允许定义重命名的优先级。有关过滤器、条件以及可能包含在其中的各种运算符的信息,请参阅过滤器部分。

“format_string”定义如何重命名匹配过滤器的文件。它不能包含/字符,除非它表示运算符(因为文件名不能包含/)。在最简单的情况下,它只是一个将文件重命名为的字符串,但该字符串可以包含任意数量/组合的运算符。有关格式字符串和其中可能包含的各种运算符的信息,请参阅格式字符串部分。

运动模式

"movement_schema": [
  {
    "filter": ["condition 1", "condition 2", ...],
    "subfolder": "<format string 1>",
    "sublevels": [
      {
        "filter": ["condition 3", "condition 4", ...],
        "subfolder": "<format string 2>",
        "sublevels": [...]
      },
      ...
    ]
  },
  ...
]

“movement_schema”通过嵌套过滤器迭代地定义输出文件夹层次结构。在每个文件夹级别,可以存在多个过滤器,它们将文件传递到较低的子文件夹或将它们放置在当前级别。这些列表是有序的,文件将根据它们匹配的第一个过滤器进行排序,例如,如果一个文件具有tag1并且tag2在一个级别,数组中的第一个过滤器匹配tag2,第二个过滤器tag1将根据 对文件进行排序tag2。这允许定义排序的优先级。有关 过滤器、条件以及可能包含在其中的各种运算符的信息,请参阅过滤器部分。

如果“子文件夹”包含格式字符串,它将被解释并添加到文件将被放置的文件夹层次结构中(并根据“子级别”进一步排序);如果它留空"",文件将被放置在当前(在层次结构中)目录中,无需进一步排序。如果 "sublevels" 为空[],文件将被放置在指定的子文件夹中,无需进一步排序。请注意,移动模式不必为每个可能的文件都有路径。未能“找到家”的文件将留在输入文件夹中,并打印警告(除非-A指定)。有关格式字符串和其中可能包含的各种运算符的信息,请参阅 格式字符串部分。

此外,请注意完整的层次结构(即那些以显式将文件放置在文件夹中而终止的层次结构)将优于部分层次结构(即,如果文件沿层次结构向下渗透一段距离,然后不匹配过滤器)。如果找不到完整的层次结构,则将使用第一个部分移动文件。但是,依赖这种行为是不好的做法;/*|如果明确希望任何达到过滤级别的文件都驻留在那里,则应该使用运算符。

过滤器

过滤器(无论它可能出现在架构中的何处)由一组条件集定义。这些条件集在逻辑意义上通过 包含性 or进行组合,即匹配至少一个条件集对于匹配整个过滤器是必要且充分的。在最简单的情况下,条件集可能只是一个标签,例如,"filter": ["tag1", "tag2"]将匹配任何一个tag1tag2(或两者)的文件。但是,以下运算符可用于构造更复杂的条件集(无论是在过滤器中还是在条件/?|运算符中):

  • /G|-- 前缀/G|用于表示标签组而不是标签名称,例如"filter": ["/G|Group 1", "tag2"]将匹配任何文件中至少有一个标签Group 1或标签tag2(或两者)。
  • /*|-- all 运算符/*|匹配所有文件,不管它们是如何标记的。
  • /&|--/&|是一个逻辑“and”运算符,需要同时匹配两个条件,例如"filter": ["tag1/&|tag2"]将匹配同时具有and tag1的文件tag2。条件可以包含任意数量的/&|运算符,例如一个可以创建条件"tag1/&|tag2/&|/G|Group 1"
  • /!|-- not 前缀/!|否定下一个条件。 这个前缀在逻辑上必须在任何其他前缀之前,即你必须写/!|/G|<group>而不是/G|/!|<group>/!|/*|而不是/*|/!|/!|运算符 可以跟在逻辑“与”运算符之后/&|,例如"<tag1>/&|/!|<tag2>",它将匹配任何有tag1和没有的文件tag2

对于这些运算符的组合程度或过滤器可能具有的条件集数量没有(实际)限制。

格式化字符串

格式字符串只是一个可能包含也可能不包含各种运算符的字符串。解释格式字符串时,这些运算符将替换为相应的数据。

  • /EXT|-- 放在格式字符串中的任何地方,/EXT|都将替换为文件的原始扩展名,由extension匹配文件的“tag_formats”正则表达式中的组定义。如果您要重命名多种类型的文件并希望保留扩展名,这显然很有用。您几乎总是希望以/EXT|.
  • /FILE|-- 放在格式字符串中的任何地方,/FILE|都将替换为文件的原始名称,由file匹配文件的“tag_formats”正则表达式中的组定义。
  • /TAGS|-- 放在格式字符串中的任何地方,/TAGS|都将替换为原始文件上的标签。 这对于避免重命名的文件被取消标记是必要的,并且几乎总是应该包含在重命名格式字符串中。
  • /?|<condition>/T|<true text>/F|<false text>/E?|-- 条件运算符 /?|允许条件命名。如果<filter>匹配,则整个表达式将替换为<true text>; 如果不匹配,则整个表达式将替换为<false text>. 任何一个文本(或两者,但你为什么会)可能是空的。条件运算符可以采用任何可能处于过滤条件中的内容。有关过滤器、条件以及可能包含在其中的各种运算符的信息,请参阅过滤器部分。 <true text>并且<false text>可能包含其他运算符,即 /EXT|, /FILE|,/TAGS|/ITER|. 注意:条件运算符 不能嵌套或包含/?T|<tag>/|或包含/?G|<tag group>/|在替换文本中。
  • /?T|<tag>/|-- 标签条件运算符/?T|将插入标签的文字名称,<tag>如果它存在于文件中。请注意,这相当于/?|<tag>/T|/<tag>/F|/E?|; 这只是一条捷径。
  • /?G|<tag group>/|-- 标签组条件运算符/?G|将插入标签组的文字名称,<tag group>如果其标签之一存在于文件中。请注意,这相当于/?|/G|<tag group>/T|<tag group>/F|/E?|; 这只是一条捷径。
  • /?TIG|<tag group>/|-- "tag in group" 操作符是一个特殊的操作符,它将在指定标签组中的文件上插入一个标签。例如,/?TIG|group1?/|将解析为tag1if tag1is on the file and in group1,或者tag2if tag2is on the file and ingroup1. 如果文件上的多个标签在组中,则将替换第一个(按标签顺序,从左到右)。如果文件在组中缺少标签,则整个运算符将简单地为空。这种“分组中的标签”运算符对于编写无法提前预测确切标签的灵活模式最有用。例如,如果想根据关联的帐户将银行对帐单分类到文件夹中,可以使用带有“Account Number”组的“tag in group”运算符,然后只需使用各种更新标签组帐号标签,而不必指定架构中的每个帐号。例如,考虑以下情况,使用Group 1 = tag1, tag3format_string = "Tag: /?TIG|Group 1/|"
    • File [tag1, tag2]-- “标签:tag1”
    • File [tag2, tag4]- “标签: ”
    • File [tag1, tag2, tag3]--“标签:标签2”
  • /ITER|<text>/#|<other text>/EITER|--/ITER|算子复杂但重要。仅在将多个文件重命名为相同名称的情况下才调用它。在这种情况下,文本被放置在文件名中,同时/#|被替换为具有相同名称的第 n 个文件。/ITER|否则,将忽略 整个运算符。/ITER| 运算符不应在文件夹名称格式字符串中使用。它将被忽略。 本质上,/ITER|标签“计算”了相同文件名产生的次数。最好/ITER|在架构中始终包含运算符,以避免文件由于潜在的破坏而未被重命名。 /#|可能在一个运算符中出现多次/ITER|,但通常没有必要。这/ITER|运算符可以包含任何其他运算符,包括条件运算符/?|,但不能嵌套。请注意,如果文件最终名称相同但输出目录不同,则不会使用/ITER|该 运算符。它只会在必要时出现以避免破坏。一个例子将使这更容易理解。在以下情况下 考虑格式字符串:Widget/ITER| /#|/EITER|
    • 1 个匹配文件 - 文件将命名为Widget.
    • 同一文件夹中的 3 个匹配文件 - 文件将命名为Widget 1Widget 2Widget 3.
    • 3 个匹配文件,每个文件位于不同的文件夹中 - 文件都将命名为 Widget.

已知的问题

  • 只有 POSIX 隐藏文件被视为隐藏文件,即以 .点开头的文件,而不是像 Windows 那样隐藏的文件。这很可能是Won't Fix

测试

autotagical可以通过克隆这个存储库并运行来测试:

python setup.py test

从根目录中。请注意,这可能需要python3而不是python,具体取决于您的python安装。

作者

  • 天狼星斯塔尔

执照

该项目在 GNU 通用公共许可证 v3.0 下获得许可 - 请参阅 LICENSE.md文件了解详细信息

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

autotagical-1.1.0.tar.gz (63.1 kB 查看哈希)

已上传 source

内置分布

autotagical-1.1.0-py3-none-any.whl (62.8 kB 查看哈希)

已上传 py3