{"id":13595777,"url":"https://github.com/chriscz/pysorter","last_synced_at":"2025-10-14T23:31:06.918Z","repository":{"id":19565468,"uuid":"22814614","full_name":"chriscz/pysorter","owner":"chriscz","description":"A command line utility for organizing files and directories according to regex patterns.","archived":false,"fork":false,"pushed_at":"2022-11-29T14:57:57.000Z","size":184,"stargazers_count":44,"open_issues_count":12,"forks_count":17,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-01-23T02:52:23.161Z","etag":null,"topics":["cleanup","organizer","python","regex","sorting"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chriscz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-10T17:35:54.000Z","updated_at":"2024-11-13T07:10:48.000Z","dependencies_parsed_at":"2023-01-13T20:27:30.550Z","dependency_job_id":null,"html_url":"https://github.com/chriscz/pysorter","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chriscz%2Fpysorter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chriscz%2Fpysorter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chriscz%2Fpysorter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chriscz%2Fpysorter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chriscz","download_url":"https://codeload.github.com/chriscz/pysorter/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236533063,"owners_count":19164358,"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":["cleanup","organizer","python","regex","sorting"],"created_at":"2024-08-01T16:01:57.376Z","updated_at":"2025-10-14T23:31:01.613Z","avatar_url":"https://github.com/chriscz.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"[![GitHub version](https://badge.fury.io/gh/chriscz%2Fpysorter.svg)](https://badge.fury.io/gh/chriscz%2Fpysorter)\n[![PyPI version](https://badge.fury.io/py/pysorter.svg)](https://badge.fury.io/py/pysorter)\n[![Build Status](https://travis-ci.org/chriscz/pysorter.svg?branch=master)](https://travis-ci.org/chriscz/pysorter)\n[![Coverage Status](https://coveralls.io/repos/github/chriscz/pysorter/badge.svg?branch=master)](https://coveralls.io/github/chriscz/pysorter?branch=master)\n\n# Pysorter\n\nA Commandline utility for organizing files and directories according to regex patterns.\n\n## Quick Start\n  * `pip install pysorter`\n  * `pysorter`\n\n## Commandline Synopsys\n```\nusage: pysorter [-h] [-d DEST_DIR] [-p] [-t FILETYPES] [-u UNHANDLED_FILE]\n                [-r] [-c] [-n] [-V]\n                directory\n\nReorganizes files and directories according to certain rules\n\npositional arguments:\n  directory             The directory to be organized\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -d DEST_DIR, --destination DEST_DIR\n                        The destination directory to move organized files to.\n  -p, --process-dirs    Should directories also be matched against the rules?\n  -t FILETYPES, --filetypes FILETYPES\n                        File containing regex rules [Default: filetypes.py]\n  -u UNHANDLED_FILE, --unhandled-file UNHANDLED_FILE\n                        Write the paths of all unhandled items to this file\n  -r, --recursive       Recursively organize directories\n  -c, --remove-empty-dirs\n                        Recursively removes all empty directories in the\n                        directory being organized.\n  -n, --dry-run         Prints out the changes that would occur, without\n                        actually executing them.\n  -V, --version         Prints out the current version of pysorter\n```\n\n## Configuration\nPysorter ships with a default rules file that has entries for many common \nfile types. As a user of pysorter, you are encouraged to add your own rules\nusing `pysorter/filetypes.py` file for inspiration.\n\n### Example 1\nSuppose we would like all our pdfs to be placed under a pdf directory, \nlocated under `/home/chris/sorted/documents/`. As a first step we must write\na *rules* file. This file is a normal Python module that defines where\ncertain files will be moved to.\n\n```python\n    RULES = [\n        # regex pattern, destination\n        (r'.*\\.pdf$', 'documents/pdf/' ),\n    ]\n```\n\n#### Notes\n * Rules are attempted in the order they are defined. As soon as a match is found,\n   we use its destination.\n * The slash in the destination (`documents/pdf/`) is important, as all pdfs will be placed \n   in the `documents/pdf/` directory. If the slash was removed as in `document/pdf`, then all pdfs would be\n   moved to a file named `pdf` in the directory `document`. Which is definitely not what you wanted!\n * The destination could also be a Python that will be called during processing.\n\n### Example 2\nWe would like all images downloaded from facebook to be located under `images/facebook/` instead of \nputting them directly inside `images/`. You'll notice that facebook images end in `_n.jpg`.\nWe would like to strip away that prefix as well. So we write the following rule,\n\n```python\n    RULES = [\n        # ... some other rules ...\n        (r'(?P\u003cfilename\u003e[^/]+)_n.jpe?g$', 'images/facebook/{filename}.jpg')\n        # ... yet some more rules ...\n    ]\n```\n#### Notes\nThis example might look complicated, but it is really just using standard Python\nfunctionality. To break it down.\n * `(?P\u003cfilename\u003e[^/]+)` is a named capturing group, it matches any character that is not a \n   `/`, therefore the filename without extension. Here are some example matches\n\n   * `tosort/myphoto_n.jpg`. *filename=myphoto*\n   * `tosort/foo/y123_n.jpg`. *filename=y123*\n * In the destination of the rule we can make use of both named and unnamed capturing \n   groups.\n\nYou can look at the `pysorter.filetypes` module for some more inspiration.\n\n## Caveats\nThe [Python shutil library](https://docs.python.org/3/library/shutil.html) used by pysorter carries the following warning:\n\n```\nWarning \nEven the higher-level file copying functions (shutil.copy(), shutil.copy2()) cannot copy all file metadata.\n\n- On POSIX platforms, this means that file owner and group are lost as well as ACLs. \n- On Mac OS, the resource fork and other metadata are not used. \n  This means that resources will be lost and file type and \n  creator codes will not be correct. \n- On Windows, file owners, ACLs and alternate data streams are not copied.\n```\n\nIf the files are on the same filesystem, then neither `copy` nor `copy2` are actually used,\nso there shouldn't be *any* risks involved. \n\nIf you still feel unsure, feel free to [create an issue](https://github.com/chriscz/pysorter/issues/new),\nand we'll try our best to help. \n\n## Requirements\nPython version:\n * 3.3\n * 3.4\n * 3.5\n\n## Contributing\nSee the [guide](CONTRIBUTING.md).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchriscz%2Fpysorter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchriscz%2Fpysorter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchriscz%2Fpysorter/lists"}