{"id":20287598,"url":"https://github.com/rhettbull/autofile","last_synced_at":"2026-03-17T18:38:47.309Z","repository":{"id":57412764,"uuid":"420858612","full_name":"RhetTbull/autofile","owner":"RhetTbull","description":"Mac command line app to automatically move or copy files based on metadata associated with the files.  For example, file your photos based on EXIF metadata or use MP3 tags to file your music files.","archived":false,"fork":false,"pushed_at":"2024-07-10T08:58:27.000Z","size":13758,"stargazers_count":22,"open_issues_count":18,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-10-30T01:04:13.424Z","etag":null,"topics":["cli","exif","exiftool","file-manager","macos","metadata","mp3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RhetTbull.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-25T02:55:56.000Z","updated_at":"2024-10-22T03:09:39.000Z","dependencies_parsed_at":"2024-07-10T10:53:19.611Z","dependency_job_id":null,"html_url":"https://github.com/RhetTbull/autofile","commit_stats":{"total_commits":114,"total_committers":1,"mean_commits":114.0,"dds":0.0,"last_synced_commit":"4f587ad5c8df8ffc8781d8c528766e62dd18c987"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Fautofile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Fautofile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Fautofile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Fautofile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RhetTbull","download_url":"https://codeload.github.com/RhetTbull/autofile/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230516183,"owners_count":18238352,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","exif","exiftool","file-manager","macos","metadata","mp3"],"created_at":"2024-11-14T14:40:58.167Z","updated_at":"2026-03-17T18:38:47.282Z","avatar_url":"https://github.com/RhetTbull.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# autofile\n\nCommand line app (written in python) to automatically move or copy files based on metadata associated with the files.  For example, file your photos based on EXIF metadata or use MP3 tags to file your music files.\n\nautofile uses a template system to specify the target directory and/or filename based on the file's metadata.  For example:\n\n`autofile *.mp3 --target ~/Music --directory \"{audio:artist}/{audio:album}\"`\n\nWill move all mp3 files to new folders with `Artist/Album` naming scheme.\n\nThe template system is very flexible and powerful allowing you to perform transforms on the metadata fields and use conditional logic.\n\nautofile understands metadata about audio files (MP3, OGG, etc), photo \u0026 video files, macOS specific metadata such as Finder tags as well as various filesystem related metadata.\n\nPhoto and video metadata (EXIF, IPTC, XMP, etc.) requires that the third-party [exiftool](https://exiftool.org/) command line utility be installed. All other metadata works with no additional dependencies.\n\n## Examples\n\nFile image files into directory structure with format \"Camera Make/Year/Month/file.jpg\":\n\n```\n$ ls -l ~/Pictures/NewPhotos\ntotal 12160\n-rw-r--r--@ 1 user  staff  3449684 Oct 24 07:10 IMG_1234.jpeg\n-rw-r--r--@ 1 user  staff  2771656 Oct 23 12:53 IMG_1235.jpg\n\n$ autofile --target ~/Pictures/FiledPhotos \\\n--directory \"{exiftool:Make}/{exiftool:created.year}/{exiftool:created.month}\" \\\n~/Pictures/NewPhotos/*\n\nProcessing 2 files\nMoving /Users/user/Pictures/NewPhotos/IMG_1234.jpeg to /Users/user/Pictures/FiledPhotos/Apple/2021/October/IMG_1234.jpeg\nMoving /Users/user/Pictures/NewPhotos/IMG_1235.jpg to /Users/user/Pictures/FiledPhotos/Apple/2021/October/IMG_1235.jpg\nDone. Processed 2 files.\nDone.\n\n$ tree ~/Pictures/FiledPhotos\n/Users/user/Pictures/FiledPhotos\n└── Apple\n    └── 2021\n        └── October\n            ├── IMG_1234.jpeg\n            └── IMG_1235.jpg\n\n\n```\n\nFile MP3 files into directory with with format \"Artist/Album\" and rename files with format \"Track number - Track title.mp3\" (and format track to be 2 digits with leading zeros):\n\n```\n$ls -1 ~/Music/Unfiled\nfile1.mp3\nfile10.mp3\nfile11.mp3\nfile12.mp3\nfile2.mp3\nfile3.mp3\nfile4.mp3\nfile5.mp3\nfile6.mp3\nfile7.mp3\nfile8.mp3\nfile9.mp3\n\n$ autofile --target ~/Music/Filed \\\n--directory \"{audio:artist}/{audio:album}\" \\\n--filename \"{format:int:02d,{audio:track}} - {audio:title}.mp3\" \\\n~/Music/Unfiled/*.mp3\n\nProcessing 12 files\nMoving /Users/user/Music/Unfiled/file1.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/01 - Story of My Life.mp3\nMoving /Users/user/Music/Unfiled/file10.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/10 - The Mission : How Great Thou\nArt.mp3\nMoving /Users/user/Music/Unfiled/file11.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/11 - Because of You.mp3\nMoving /Users/user/Music/Unfiled/file12.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/12 - Pictures at an Exhibition.mp3\nMoving /Users/user/Music/Unfiled/file2.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/02 - Let It Go.mp3\nMoving /Users/user/Music/Unfiled/file3.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/03 - Ants Marching : Ode to Joy.mp3\nMoving /Users/user/Music/Unfiled/file4.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/04 - Fathers' Eyes.mp3\nMoving /Users/user/Music/Unfiled/file5.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/05 - Kung Fu Piano: Cello Ascends.mp3\nMoving /Users/user/Music/Unfiled/file6.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/06 - Summer Jam.mp3\nMoving /Users/user/Music/Unfiled/file7.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/07 - Batman Evolution.mp3\nMoving /Users/user/Music/Unfiled/file8.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/08 - Don't You Worry Child (feat. Shweta\nSubram).mp3\nMoving /Users/user/Music/Unfiled/file9.mp3 to /Users/user/Music/Filed/The Piano Guys/Wonders/09 - Home.mp3\nDone. Processed 12 files.\nDone.\n\n$ tree ~/Music/Filed\n/Users/user/Music/Filed\n└── The\\ Piano\\ Guys\n    └── Wonders\n        ├── 01\\ -\\ Story\\ of\\ My\\ Life.mp3\n        ├── 02\\ -\\ Let\\ It\\ Go.mp3\n        ├── 03\\ -\\ Ants\\ Marching\\ :\\ Ode\\ to\\ Joy.mp3\n        ├── 04\\ -\\ Fathers'\\ Eyes.mp3\n        ├── 05\\ -\\ Kung\\ Fu\\ Piano:\\ Cello\\ Ascends.mp3\n        ├── 06\\ -\\ Summer\\ Jam.mp3\n        ├── 07\\ -\\ Batman\\ Evolution.mp3\n        ├── 08\\ -\\ Don't\\ You\\ Worry\\ Child\\ (feat.\\ Shweta\\ Subram).mp3\n        ├── 09\\ -\\ Home.mp3\n        ├── 10\\ -\\ The\\ Mission\\ :\\ How\\ Great\\ Thou\\ Art.mp3\n        ├── 11\\ -\\ Because\\ of\\ You.mp3\n        └── 12\\ -\\ Pictures\\ at\\ an\\ Exhibition.mp3\n```\n\n## Supported Platforms\n\nCurrently tested on macOS and Ubuntu Linux. Tested on macOS 13.7.1 (Ventura) but should work fine on newer versions. Some of the features such as Finder tags are macOS specific and will not be available on other platforms.\n\nOn macOS, copy and move use native macOS API calls to take advantage of advanced features such as copy-on-write that are not available with the standard python system calls.\n\n## Cautions and Warnings\n\nThis software is feature complete but not yet fully tested.  No warranty of any kind is implied or provided.  Please ensure you have a backup before using this software as it can rename and move your files with no undo feature.  I recommend you always run autofile with the `--dry-run` flag first to ensure you understand exactly what it will do.\n\n## Contributions\n\nContributions of all kinds are welcome!  If you find a bug or have an idea to improve autofile, please [open an issue](https://github.com/RhetTbull/autofile/issues)!\n\n## Command Line Reference\n\n```\n$ autofile --help\nUsage: autofile [OPTIONS] FILES...\n\n  move or copy files into directories based on a metadata template string\n\nRequired: [all required]\n  -t, --target TARGET_DIRECTORY  Target destination directory.\n\nFiling templates: [at least 1 required]\n  -D, --directory DIRECTORY_TEMPLATE\n                                 Directory template for exporting files.\n  -F, --filename FILENAME_TEMPLATE\n                                 Filename template for exporting files.\n\nFilter Options:\n  -g, --glob PATTERN             Filter files to process with a glob pattern,\n                                 e.g. '--glob \"*.jpg\"' --glob may be repeated\n                                 to use more than one pattern. Multiple\n                                 patterns treated as \"AND\", that is, a file\n                                 that matches all patterns will be processed.\n  -r, --regex PATTERN            Filter files to process with a regex pattern,\n                                 e.g. '--regex \"IMG_[1-3].*\"' --regex may be\n                                 repeated to use more than one pattern.\n                                 Multiple patterns treated as \"AND\", that is, a\n                                 file that matches all patterns will be\n                                 processed. Any valid python regular express\n                                 may be used.\n  -f, --filter TEMPLATE_PATTERN  Filter files to process that match a metadata\n                                 template pattern, e.g. '--filter\n                                 \"{mdls:kMDItemKind contains image}\"'. --filter\n                                 matches the file if TEMPLATE_PATTERN evaluates\n                                 to a non-null value. --filter may be repeated\n                                 to use more than one pattern. Multiple\n                                 patterns treated as \"AND\", that is, a file\n                                 that matches all patterns will be processed.\n\nOptions:\n  -w, --walk                     Recursively walk directories.\n  -Q, --quiet                    Turn off verbose output.\n  -c, --copy                     Copy files instead of moving them.\n  -h, --hardlink                 Hardlink files instead of moving them.\n  -d, --dry-run                  Dry run mode; do not actually move/copy any\n                                 files.\n\nOther options:\n  --version                      Show the version and exit.\n  --help                         Show this message and exit.\n\nTemplate System\n\nautofile contains a rich templating system which allows fine-grained control\nover the output format of metadata. The templating system converts one or\ntemplate statements, written in metadata templating language (MTL), to one or\nmore rendered values using metadata information from the file being processed.\n\nIn its simplest form, a template statement has the form: \"{template_field}\",\nfor example \"{size}\" which resolves to the size of the file. Template fields\nmay also have subfields delineated by a : as in \"{audio:artist}\" which resolves\nto the artist name for an audio file (e.g. mp3).  In this example, the field is\naudio and the subfield is artist.  Template fields may also have attributes\ndelineated by a . as in \"{created.year}\" which resolves to the 4-digit year of\nthe file creation date. In this example, the field is created and the attribute\nis year.\n\nTemplate statements may contain one or more modifiers.  The full syntax is:\n\n\"pretext{delim+template_field:subfield|filter[find,replace]\nconditional?bool_value,default}posttext\"\n\nTemplate statements are white-space sensitive meaning that white space (spaces,\ntabs) changes the meaning of the template statement.\n\npretext and posttext are free form text.  For example, if an image file has\nTitle (e.g. XMP:Title) \"My file Title\". the template statement \"The title of\nthe file is {exiftool:Title}\", resolves to \"The title of the file is My file\nTitle\".  The pretext in this example is \"The title if the file is \" and the\ntemplate_field is {Title}.  Note: some punctuation such as commas cannot be\nused in the pretext or posttext.  For this reason, the template system provides\nspecial punctuation templates like {comma} to insert punctuation where needed.\nFor example: {exiftool:Make}{comma}{exiftool:Model} could resolve to\nApple,iPhone SE.\n\nDelimiter\n\ndelim: optional delimiter string to use when expanding multi-valued template\nvalues in-place\n\n+: If present before template name, expands the template in place.  If delim\nnot provided, values are joined with no delimiter.\n\ne.g. if image file keywords are [\"foo\",\"bar\"]:\n\n • \"{exiftool:Keywords}\" renders to \"foo\", \"bar\"\n • \"{,+exiftool:Keywords}\" renders to: \"foo,bar\"\n • \"{; +exiftool:Keywords}\" renders to: \"foo; bar\"\n • \"{+exiftool:Keywords}\" renders to \"foobar\"\n\ntemplate_field: The template field to resolve.\n\n:subfield: Templates may have sub-fields; reserved for future use.\n\nFilters\n\n|filter: You may optionally append one or more filter commands to the end of\nthe template field using the vertical pipe ('|') symbol.  Filters may be\ncombined, separated by '|' as in: {user|capitalize|parens}.\n\nValid filters are:\n\n • lower: Convert value to lower case, e.g. 'Value' =\u003e 'value'.\n • upper: Convert value to upper case, e.g. 'Value' =\u003e 'VALUE'.\n • strip: Strip whitespace from beginning/end of value, e.g. ' Value ' =\u003e\n   'Value'.\n • titlecase: Convert value to title case, e.g. 'my value' =\u003e 'My Value'.\n • capitalize: Capitalize first word of value and convert other words to lower\n   case, e.g. 'MY VALUE' =\u003e 'My value'.\n • braces: Enclose value in curly braces, e.g. 'value =\u003e '{value}'.\n • parens: Enclose value in parentheses, e.g. 'value' =\u003e '(value').\n • brackets: Enclose value in brackets, e.g. 'value' =\u003e '[value]'.\n • split(x): Split value into a list of values using x as delimiter, e.g.\n   'value1;value2' =\u003e ['value1', 'value2'] if used with split(;).\n • autosplit: Automatically split delimited string into separate values (for\n   example, keyword string in docx files); will split strings delimited by\n   comma, semicolon, or space, e.g. 'value1,value2' =\u003e ['value1', 'value2'].\n • chop(x): Remove x characters off the end of value, e.g. chop(1): 'Value' =\u003e\n   'Valu'; when applied to a list, chops characters from each list value, e.g.\n   chop(1): [\"travel\", \"beach\"]=\u003e [\"trave\", \"beac\"].\n • chomp(x): Remove x characters from the beginning of value, e.g. chomp(1):\n   ['Value'] =\u003e ['alue']; when applied to a list, removes characters from each\n   list value, e.g. chomp(1): [\"travel\", \"beach\"]=\u003e [\"ravel\", \"each\"].\n • sort: Sort list of values, e.g. ['c', 'b', 'a'] =\u003e ['a', 'b', 'c'].\n • rsort: Sort list of values in reverse order, e.g. ['a', 'b', 'c'] =\u003e ['c',\n   'b', 'a'].\n • reverse: Reverse order of values, e.g. ['a', 'b', 'c'] =\u003e ['c', 'b', 'a'].\n • uniq: Remove duplicate values, e.g. ['a', 'b', 'c', 'b', 'a'] =\u003e ['a', 'b',\n   'c'].\n • join(x): Join list of values with delimiter x, e.g. join(:): ['a', 'b', 'c']\n   =\u003e 'a:b:c'; the DELIM option functions similar to join(x) but with DELIM,\n   the join happens before being passed to any filters.\n • append(x): Append x to list of values, e.g. append(d): ['a', 'b', 'c'] =\u003e\n   ['a', 'b', 'c', 'd'].\n • prepend(x): Prepend x to list of values, e.g. prepend(d): ['a', 'b', 'c'] =\u003e\n   ['d', 'a', 'b', 'c'].\n • appends(x): [append s(tring)] Append x to each value of list of values, e.g.\n   appends(d): ['a', 'b', 'c'] =\u003e ['ad', 'bd', 'cd'].\n • prepends(x): [prepend s(tring)] Prepend x to each value of list of values,\n   e.g. prepends(d): ['a', 'b', 'c'] =\u003e ['da', 'db', 'dc'].\n • remove(x): Remove x from list of values, e.g. remove(b): ['a', 'b', 'c'] =\u003e\n   ['a', 'c'].\n • slice(start:stop:step): Slice list using same semantics as Python's list\n   slicing, e.g. slice(1:3): ['a', 'b', 'c', 'd'] =\u003e ['b', 'c']; slice(1:4:2):\n   ['a', 'b', 'c', 'd'] =\u003e ['b', 'd']; slice(1:): ['a', 'b', 'c', 'd'] =\u003e ['b',\n   'c', 'd']; slice(:-1): ['a', 'b', 'c', 'd'] =\u003e ['a', 'b', 'c']; slice(::-1):\n   ['a', 'b', 'c', 'd'] =\u003e ['d', 'c', 'b', 'a']. See also sslice().\n • sslice(start:stop:step): [s(tring) slice] Slice values in a list using same\n   semantics as Python's string slicing, e.g. sslice(1:3):'abcd =\u003e 'bc';\n   sslice(1:4:2): 'abcd' =\u003e 'bd', etc. See also slice().\n\ne.g. if file keywords are [\"FOO\",\"bar\"]:\n\n • \"{exiftool:Keywords|lower}\" renders to \"foo\", \"bar\"\n • \"{exiftool:Keywords|upper}\" renders to: \"FOO\", \"BAR\"\n • \"{exiftool:Keywords|capitalize}\" renders to: \"Foo\", \"Bar\"\n • \"{exiftool:Keywords|lower|parens}\" renders to: \"(foo)\", \"(bar)\"\n\ne.g. if an image file description is \"my description\":\n\n • \"{exiftool:Description|titlecase}\" renders to: \"My Description\"\n\nFind/Replace\n\n[find,replace]: optional text replacement to perform on rendered template\nvalue.  For example, to replace \"/\" in a a keyword, you could use the template\n\"{exiftool:Keywords[/,-]}\".  Multiple replacements can be made by appending \"|\"\nand adding another find|replace pair.  e.g. to replace both \"/\" and \":\" in\nkeywords: \"{exiftool:Keywords[/,-|:,-]}\".  find/replace pairs are not limited\nto single characters.  The \"|\" character cannot be used in a find/replace pair.\n\nConditional Operators\n\nconditional: optional conditional expression that is evaluated as boolean\n(True/False) for use with the ?bool_value modifier.  Conditional expressions\ntake the form 'not operator value' where not is an optional modifier that\nnegates the operator.  Note: the space before the conditional expression is\nrequired if you use a conditional expression.  Valid comparison operators are:\n\n • contains: template field contains value, similar to python's in\n • matches: template field contains exactly value, unlike contains: does not\n   match partial matches\n • startswith: template field starts with value\n • endswith: template field ends with value\n • \u003c=: template field is less than or equal to value\n • \u003e=: template field is greater than or equal to value\n • \u003c: template field is less than value\n • \u003e: template field is greater than value\n • ==: template field equals value\n • !=: template field does not equal value\n\nMultiple values may be separated by '|' (the pipe symbol) when used with\ncontains, matches, startswith, and endswith.  value is itself a template\nstatement so you can use one or more template fields in value which will be\nresolved before the comparison occurs. When applied to multi-valued fields (ie.\nlists), the comparison is applied to each value in the list and evaluates to\nTrue if any of the values match.\n\nFor example:\n\n • {exiftool:Keywords matches Beach} resolves to True if 'Beach' is a keyword.\n   It would not match keyword 'BeachDay'.\n • {exiftool:Keywords contains Beach} resolves to True if any keyword contains\n   the word 'Beach' so it would match both 'Beach' and 'BeachDay'.\n • {ISO \u003c 100} resolves to True if the file's ISO is \u003c 100.\n • {exiftool:Keywords|lower contains beach} uses the lower case filter to do\n   case-insensitive matching to match any keyword that contains the word\n   'beach'.\n • {exiftool:Keywords|lower not contains beach} uses the not modifier to negate\n   the comparison so this resolves to True if there is no keyword that matches\n   'beach'.\n • {docx:author startswith John} resolves to True if the author of a docx file\n   starts with 'John'.\n • {audio:bitrate == 320} resolves to True if the audio file's bitrate is 320\n   kbps.\n\nBoolean Values\n\n?bool_value: Template fields may be evaluated as boolean (True/False) by\nappending \"?\" after the field name or \"[find/replace]\".  If a field is True or\nhas any value, the value following the \"?\" will be used to render the template\ninstead of the actual field value.  If the template field evaluates to False or\nhas no value (e.g. file has no title and field is \"{audio:title}\") then the\ndefault value following a \",\" will be used.\n\ne.g. if file has a title\n\n • \"{audio:title?I have a title,I do not have a title}\" renders to \"I have a\n   title\"\n\nand if it does not have a title:\n\n • \"{audio:title?I have a title,I do not have a title}\" renders to \"I do not\n   have a title\"\n\nDefault Values\n\n,default: optional default value to use if the template name has no value.\nThis modifier is also used for the value if False for boolean-type fields (see\nabove) as well as to hold a sub-template for values like {created.strftime}.\nIf no default value provided and the field is null, autofile will use a default\nvalue of '_' (underscore character).\n\nTemplate fields such as created.strftime use the default value to pass the\ntemplate to use for strftime.\n\ne.g., if file date is 4 February 2020, 19:07:38,\n\n • \"{created.strftime,%Y-%m-%d-%H%M%S}\" renders to \"2020-02-04-190738\"\n\nSpecial Characters\n\nIf you want to include \"{\" or \"}\" in the output, use \"{openbrace}\" or\n\"{closebrace}\" template substitution.\n\ne.g. \"{created.year}/{openbrace}{audio.title}{closebrace}\" would result in\n\"2020/{file Title}\".\n\nField Attributes\n\nSome templates have additional modifiers that can be appended to the template\nname using dot notation to access specific attributes of the template field.\nFor example, the {filepath} template returns the path of the file being\nprocessed and {filepath.parent} returns the parent directory.\n\nVariables\n\nYou can define variables for later use in the template string using the format\n{var:NAME,VALUE}.  Variables may then be referenced using the format %NAME. For\nexample: {var:foo,bar} defines the variable %foo to have value bar. This can be\nuseful if you want to re-use a complex template value in multiple places within\nyour template string or for allowing the use of characters that would otherwise\nbe prohibited in a template string. For example, the \"pipe\" (|) character is\nnot allowed in a find/replace pair but you can get around this limitation like\nso: {var:pipe,{pipe}}{audio:title[-,%pipe]} which replaces the - character with\n| (the value of %pipe).\n\nVariables can also be referenced as fields in the template string, for example:\n{var:year,{created.year}}{filepath.stem}-{%year}{filepath.suffix}. In some cases,\nuse of variables can make your template string more readable.  Variables can be\nused as template fields, as values for filters, as values for conditional\noperations, or as default values.  When used as a conditional value or default\nvalue, variables should be treated like any other field and enclosed in braces\nas conditional and default values are evaluated as template strings. For\nexample: `{var:name,John}{docx:author contains {%name}?{%name},Not-{%name}}\n\nIf you need to use a % (percent sign character), you can escape the percent\nsign by using %%.  You can also use the {percent} template field where a\ntemplate field is required. For example:\n\n{audio:title[:,%%]} replaces the : with % and {audio:title contains\nFoo?{audio:title}{percent},{audio:title}} adds % to the audio title if it\ncontains Foo.\n\nPunctuation Fields\n\nField           Description\n{comma}         A comma: ','\n{semicolon}     A semicolon: ';'\n{questionmark}  A question mark: '?'\n{pipe}          A vertical pipe: '|'\n{percent}       A percent sign: '%'\n{openbrace}     An open brace: '{'\n{closebrace}    A close brace: '}'\n{openparens}    An open parentheses: '('\n{closeparens}   A close parentheses: ')'\n{openbracket}   An open bracket: '['\n{closebracket}  A close bracket: ']'\n{newline}       A newline: '\\n'\n{lf}            A line feed: '\\n', alias for {newline}\n{cr}            A carriage return: '\\r'\n{crlf}          a carriage return + line feed: '\\r\\n'\n\nWithin the template system, many punctuation characters have special meaning,\ne.g. {} indicates a template field and this means that some punctuation\ncharacters cannot be inserted into the template. Thus, if you want to insert\npunctuation into the rendered template value, you can use these punctuation\nfields to do so. For example, {openbrace}value{closebrace} will render to\n{value}.\n\nString Formatting Fields\n\nField     Description\n{strip}   Use in form '{strip,TEMPLATE}'; strips whitespace from beginning and\n          end of rendered TEMPLATE value(s).\n{format}  Use in form, '{format:TYPE:FORMAT,TEMPLATE}'; converts TEMPLATE value\n          to TYPE then formats the value using python string formatting codes\n          specified by FORMAT; TYPE is one of: 'int', 'float', or 'str'.\n\nThe {strip} and {format} fields are used to format strings. {strip,TEMPLATE}\nstrips whitespace from TEMPLATE. For example, {strip,{exiftool:Title}} will\nstrip any excess whitespace from the title of an image file.\n\n{format:TYPE:FORMAT,TEMPLATE} formats TEMPLATE using python string formatting\ncodes. For example:\n\n • {format:int:02d,{audio:track}} will format the track number of an audio file\n   to two digits with leading zeros.\n • {format:str:-^30,{audio.title}} will center the title of an audio file and\n   pad it to 30 characters with '-'.\n\nTYPE must be one of 'int', 'float', or 'str'.\n\nFORMAT may be a string or an variable. A variable may be helpful when you need\nto use a character in the format string that would otherwise not be allowed.\nFor example, to use a comma separator, you could do this:\n\n{var:commaformat,{comma}}{format:int:%commaformat,{created.year}} which\ntransforms \"2021\" to \"2,021\"\n\nSee https://docs.python.org/3.7/library/string.html#formatspec for more\ninformation on valid FORMAT values.\n\nFile Information Fields\n\nField    Description\n{size}   Size of file in bytes\n{uid}    User identifier of the file owner\n{gid}    Group identifier of the file owner\n{user}   User name of the file owner\n{group}  Group name of the file owner\n\nDate/Time Fields\n\nField       Description\n{created}   File creation date/time (MacOS only; only other platforms returns\n            file inode change time)\n{modified}  File modification date/time\n{accessed}  File last accessed date/time\n{today}     The current date/time (as of when {today} is first evaluated)\n{now}       The current date/time (evaluated at the time the template is\n            processed)\n\nDate/time fields may be formatted using \"dot notation\" attributes which are\nappended to the field name following a . (period). For example, {created.month}\nresolves to the month name of the file's creation date in the user's locale,\ne.g. December.\n\nThe {today} and {now} fields resolve to the current date/time with one key\ndistinction between them: {today} is the current date/time as of when {today}\nis first evaluated and will remain unchanged for every file processed; {now} is\nthe current date/time at the time each template is processed and will change\nwith every file processed.\n\nThe following attributes are available:\n\nAttribute  Description\ndate       ISO date, e.g. 2020-03-22\nyear       4-digit year, e.g. 2021\nyy         2-digit year, e.g. 21\nmonth      Month name as locale's full name, e.g. December\nmon        Month as locale's abbreviated name, e.g. Dec\nmm         2-digit month, e.g. 12\ndd         2-digit day of the month, e.g. 22\ndow        Day of the week as locale's full name, e.g. Tuesday\ndoy        Julian day of year starting from 001\nhour       2-digit hour, e.g. 10\nmin        2-digit minute, e.g. 15\nsec        2-digit second, e.g. 30\nstrftime   Apply strftime template to date/time. Should be used in form\n           {created.strftime,TEMPLATE} where TEMPLATE is a valid strftime\n           template, e.g. {created.strftime,%Y-%U} would result in year-week\n           number of year: '2020-23'. If used with no template will return null\n           value. See https://strftime.org/ for help on strftime templates.\n\nFile Path Fields\n\nField       Description\n{filepath}  The full path to the file being processed\n\nThe {filepath} fields returns the full path to the source file being processed.\nVarious attributes of the path can be accessed using \"dot notation\" (appended\nto the filepath field with a '.'). For example, {filepath.name} returns just\nthe name of the file without the full path. {filepath.parent} returns the\nparent directory of the file.\n\nPath attributes can be chained, for example {filepath.parent.name} returns just\nthe name of the immediate parent directory without the full directory path.\n\nFor example, if the field {filepath} is '/Shared/files/IMG_1234.JPG':\n\n • {filepath.parent} is '/Shared/files'\n • {filepath.name} is 'IMG_1234.JPG'\n • {filepath.stem} is 'IMG_1234'\n • {filepath.suffix} is '.JPG'\n\nThe following attributes are available:\n\nSubfield  Description\nname      The name of the file\nstem      The name of the file without the suffix (extension)\nsuffix    The suffix (extension) of the file, including the leading `.`\nparent    The parent directory of the file\n\nmacOS Metadata Fields\n\nField   Description\n{mdls}  Get metadata attributes for file as returned by mdls command; use in\n        form '{mdls:ATTRIBUTE}', for example, '{mdls:kMDItemContentType}'\n\n{mdls:ATTRIBUTE} returns the value of the metadata ATTRIBUTE as returned by the\nmacOS mdls command. For example, {mdls:kMDItemContentType} returns the content\ntype of the file, e.g. public.python-script or public.mp3 and\n{mdls:kMDItemKind} returns a description of file type, e.g. Python Script or\nMP3 Audio. Available only on macOS.\n\nFinder Metadata\n\nField     Description\n{finder}  Get metadata managed by macOS Finder such as tags and comments; use\n          in form '{finder:SUBFIELD}', e.g. '{finder:tags}'\n\n{finder} provides access to Finder metadata; available only on macOS. It must\nbe used in the form {finder:SUBFIELD} where SUBFIELD is one of the following:\n\nSubfield  Description\ntags      Finder tags (keywords)\ncomment   Finder comment\n\nUniform Type Identifier (UTI) Fields\n\nField  Description\n{uti}  Uniform Type Identifier (UTI) for file\n\nThe {uti} template returns the macOS Uniform Type Identifier (UTI) for the\nfile. For example, {uti} for a file with extension .pdf would return\ncom.adobe.pdf. Available only on macOS.\n\nAudio Files\n\nField    Description\n{audio}  Use in form '{audio:TAG}'; Returns tag value for various audio types\n         include mp3,\n\nThe {audio} field provides access to audio-file related tags for audio files.\nThe following formats are supported:\n\n • MP3 (ID3 v1, v1.1, v2.2, v2.3+)\n • Wave/RIFF\n • OGG\n • OPUS\n • FLAC\n • WMA\n • MP4/M4A/M4B\n • AIFF/AIFF-C\n\nThe {audio} field must be used with one or more the following subfields in the\nform: {audio:SUBFIELD}, for example: {audio:title} or {audio:artist}.\n\nSubfield      Description\nalbum         album as string\nalbumartist   album artist as string\nartist        artist name as string\naudio_offset  number of bytes before audio data begins\nbitrate       bitrate in kBits/s\ncomment       file comment as string\ncomposer      composer as string\ndisc          disc number\ndisc_total    the total number of discs\nduration      duration of the song in seconds\nfilesize      file size in bytes\ngenre         genre as string\nsamplerate    samples per second\ntitle         title of the song\ntrack         track number as string\ntrack_total   total number of tracks as string\nyear          year or data as string\n\nPhoto and Video Files\n\nField       Description\n{exiftool}  Format: '{exiftool:GROUP:TAGNAME}'; use exiftool\n            (https://exiftool.org) to extract metadata, in form GROUP:TAGNAME\n            or TAGNAME, from image. E.g. '{exiftool:Make}' to get camera make,\n            or {exiftool:IPTC:Keywords} to extract keywords. See\n            https://exiftool.org/TagNames/ for list of valid tag names.  Group\n            name is optional (e.g. EXIF, IPTC, etc) but if specified, should be\n            the same as used in `exiftool -G`, e.g. '{exiftool:EXIF:Make}'.\n            exiftool must be installed in the path to use this template field\n            (https://exiftool.org/).\n\nThe {exiftool} template uses the third-party exiftool app\n(https://exiftool.org) to extract metadata from photo and video files.\n\nIt must be used with one or more subfields which are exiftool tags, for\nexample: {exiftool:EXIF:Make} for camera make, or {exiftool:IPTC:Keywords} for\nkeywords. The exiftool Group name (e.g. IPTC) is optional.\n\nThere are two derived subfields: created and modified which represent the\ncreated date or the modified date, respectively. These subfields are datetime\nvalues and you can access the various attributes of the datetime by using an\nattribute name following a period, e.g. {exiftool:created.year} for the 4-digit\nyear.\n\nThe following attributes are supported:\n\nAttribute  Description\ndate       ISO date, e.g. 2020-03-22\nyear       4-digit year, e.g. 2021\nyy         2-digit year, e.g. 21\nmonth      Month name as locale's full name, e.g. December\nmon        Month as locale's abbreviated name, e.g. Dec\nmm         2-digit month, e.g. 12\ndd         2-digit day of the month, e.g. 22\ndow        Day of the week as locale's full name, e.g. Tuesday\ndoy        Julian day of year starting from 001\nhour       2-digit hour, e.g. 10\nmin        2-digit minute, e.g. 15\nsec        2-digit second, e.g. 30\nstrftime   Apply strftime template to date/time. Should be used in form\n           {created.strftime,TEMPLATE} where TEMPLATE is a valid strftime\n           template, e.g. {created.strftime,%Y-%U} would result in year-week\n           number of year: '2020-23'. If used with no template will return null\n           value. See https://strftime.org/ for help on strftime templates.\n\nAdobe PDF Document Fields\n\nField  Description\n{pdf}  Access metadata properties of Adobe PDF files (.pdf); use in format\n       {pdf:SUBFIELD}\n\nAccess metadata properties of Adobe PDF files (.pdf). Use in format\n{pdf:SUBFIELD} where SUBFIELD is one of the following:\n\nSubfield  Description\nauthor    Author of the document.\ncreator   The application that created the document.\nproducer  The application the produced the PDF (may be different than creator).\ncreated   Date of creation of the document; a date/time value.\nmodified  Date on which the document was changed; a date/time value.\nsubject   The topic of the content of the document.\ntitle     The name given to the document.\nkeywords  Keywords associated with the document; a string of delimited words.\n\nIf the subfield is a date/time value (created, modified) the following\nattributes are available in dot notation (e.g. {pdf:created.year}):\n\nAttribute  Description\ndate       ISO date, e.g. 2020-03-22\nyear       4-digit year, e.g. 2021\nyy         2-digit year, e.g. 21\nmonth      Month name as locale's full name, e.g. December\nmon        Month as locale's abbreviated name, e.g. Dec\nmm         2-digit month, e.g. 12\ndd         2-digit day of the month, e.g. 22\ndow        Day of the week as locale's full name, e.g. Tuesday\ndoy        Julian day of year starting from 001\nhour       2-digit hour, e.g. 10\nmin        2-digit minute, e.g. 15\nsec        2-digit second, e.g. 30\nstrftime   Apply strftime template to date/time. Should be used in form\n           {docx:created.strftime,TEMPLATE} where TEMPLATE is a valid strftime\n           template, e.g. {docx:created.strftime,%Y-%U} would result in year-\n           week number of year: '2020-23'. If used with no template will return\n           null value. See https://strftime.org/ for help on strftime\n           templates.\n\nMicrosoft Word Document Fields\n\nField   Description\n{docx}  Access metadata properties of Microsoft Word document files (.docx);\n        use in format {docx:SUBFIELD}\n\nAccess metadata properties of Microsoft Word document files (.docx). Use in\nformat {docx:SUBFIELD} where SUBFIELD is one of the following:\n\nSubfield          Description\nauthor            Named ‘creator’ in spec. An entity primarily responsible for\n                  making the content of the resource. (Dublin Core)\ncategory          A categorization of the content of this package. Example\n                  values for this property might include: Resume, Letter,\n                  Financial Forecast, Proposal, Technical Presentation, and so\n                  on. (Open Packaging Conventions)\ncomments          Named ‘description’ in spec. An explanation of the content of\n                  the resource. Values might include an abstract, table of\n                  contents, reference to a graphical representation of content,\n                  and a free-text account of the content. (Dublin Core)\ncontent_status    The status of the content. Values might include “Draft”,\n                  “Reviewed”, and “Final”. (Open Packaging Conventions)\ncreated           Date of creation of the resource; a date/time value. (Dublin\n                  Core)\nidentifier        An unambiguous reference to the resource within a given\n                  context. (Dublin Core)\nkeywords          A delimited set of keywords to support searching and\n                  indexing. This is typically a list of terms that are not\n                  available elsewhere in the properties. (Open Packaging\n                  Conventions)\nlanguage          The language of the intellectual content of the resource.\n                  (Dublin Core)\nlast_modified_by  The user who performed the last modification. The\n                  identification is environment-specific. Examples include a\n                  name, email address, or employee ID. It is recommended that\n                  this value be as concise as possible. (Open Packaging\n                  Conventions)\nlast_printed      The date and time of the last printing; a date/time value.\n                  (Open Packaging Conventions)\nmodified          Date on which the resource was changed; a date/time value.\n                  (Dublin Core)\nrevision          The revision number. This value might indicate the number of\n                  saves or revisions, provided the application updates it after\n                  each revision. (Open Packaging Conventions)\nsubject           The topic of the content of the resource. (Dublin Core)\ntitle             The name given to the resource. (Dublin Core)\nversion           The version designator. This value is set by the user or by\n                  the application. (Open Packaging Conventions)\n\nIf the subfield is a date/time value (created, modified, last_printed) the\nfollowing attributes are available in dot notation (e.g. {docx:created.year}):\n\nAttribute  Description\ndate       ISO date, e.g. 2020-03-22\nyear       4-digit year, e.g. 2021\nyy         2-digit year, e.g. 21\nmonth      Month name as locale's full name, e.g. December\nmon        Month as locale's abbreviated name, e.g. Dec\nmm         2-digit month, e.g. 12\ndd         2-digit day of the month, e.g. 22\ndow        Day of the week as locale's full name, e.g. Tuesday\ndoy        Julian day of year starting from 001\nhour       2-digit hour, e.g. 10\nmin        2-digit minute, e.g. 15\nsec        2-digit second, e.g. 30\nstrftime   Apply strftime template to date/time. Should be used in form\n           {docx:created.strftime,TEMPLATE} where TEMPLATE is a valid strftime\n           template, e.g. {docx:created.strftime,%Y-%U} would result in year-\n           week number of year: '2020-23'. If used with no template will return\n           null value. See https://strftime.org/ for help on strftime\n           templates.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhettbull%2Fautofile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhettbull%2Fautofile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhettbull%2Fautofile/lists"}