Skip to content

Instantly share code, notes, and snippets.

@mick-io
Created December 15, 2020 20:38
Show Gist options
  • Save mick-io/7d29b1fd64c45c9fb2754a1e2f7a82c8 to your computer and use it in GitHub Desktop.
Save mick-io/7d29b1fd64c45c9fb2754a1e2f7a82c8 to your computer and use it in GitHub Desktop.
A python script for sorting the files within the passed directories by file extensions. A new directory will be created for each file extensions within the passed parent directory with the respective extensions names. Files with matching extensions will be moved into the new directory
#!/usr/bin/env python3
"""Sort Extensions
This script sorts the files within the passed directories by file extensions. A
new directory will be created for each file extensions within the passed parent
directory with the respective extensions names. Files with matching extensions
will be moved into the new directory.
BEFORE FILE TREE EXAMPLE:
.
├── image1.jpg
├── image1.raw
├── image2.jpg
└── image2.raw
AFTER FILE TREE EXAMPLE:
.
├── jpg
│  ├── image1.jpg
│   └── image2.jpg
└── raw
  ├── image1.raw
   └── image2.raw
This file can be imported as a module and contains the following function(s):
* sort_extension - sorts the files with in the passed directory into new
directories based on their extensions
"""
import os
from pathlib import Path
from typing import Dict, List
from argparse import ArgumentParser
def sort_extensions(path: Path, ignore=[]) -> List[Path]:
"""sort_extensions sorts the files within the passed directory by file
extensions. A new directory will be created for each file extensions within
the passed parent directory with the respective extensions names. Files
with matching extensions will be moved into the new directory.
Parameters
----------
path: pathlib.Path
The file path object of the parent directory to be sorted.
ignore: List[str], optional
A list of file extensions to ignore
Raises
------
Exception
if the past Path object is not a directory
Returns
-------
List[Path]
A list of of the newly created directories as pathlib.Path objects.
"""
# Removing the '.' from file extensions passed to to the 'ignore' list and
# ensuring they're lowercased
for i, ext in enumerate(ignore):
if ext.startswith('.'):
ignore[i] = ext[1:].lower()
if not path.is_dir():
raise Exception(f"{path} is not a directory")
extensions_map = _create_extensions_map(path, ignore)
dest_directories = []
for new_dir_name, file_paths in extensions_map.items():
dest_dir = Path(os.path.join(path, new_dir_name))
if not dest_dir.exists():
# Create the destination directory if it does not already exist.
os.mkdir(dest_dir)
dest_directories.append(dest_dir)
for original_path in file_paths:
new_path = os.path.join(dest_dir, original_path.name)
os.rename(original_path, new_path)
return dest_directories
def _create_extensions_map(dir_path: Path, ignore=[]) -> Dict[str, List[Path]]:
extensions_map = {}
# iterating over the contents of the passed path
for item in os.listdir(dir_path):
path = Path(os.path.join(dir_path, item))
if path.is_dir():
continue
file_name, file_extensions = os.path.splitext(item)
if not file_name or not file_extensions:
# Skip dot files and files without extensions
continue
if file_extensions.startswith('.'):
# Remove the '.' from the front of the file extensions
file_extensions = file_extensions[1:]
if file_extensions.lower() in ignore:
# Skip extensions present in the 'ignore' list.
continue
if file_extensions not in extensions_map:
extensions_map[file_extensions] = []
extensions_map[file_extensions].append(path)
return extensions_map
def __parse_arguments() -> 'args':
parser = ArgumentParser(
description="""A script for organizing files by extensions. A new
directories will be created for each file extensions within the passed
parent directory with the respective extensions names. Files with
matching extensions will be moved into the new directory.""")
parser.add_argument("directories", type=str, nargs="*", default=[os.getcwd()],
help="The path of directories that contain the target files (defaults to cwd)")
parser.add_argument("-i", "--ignore", required=False, default=[],
type=str, nargs="*", help="a list of file extensions to ignore")
return parser.parse_args()
def _sort_extensions():
args = __parse_arguments()
paths = list(args.directories)
for p in paths:
sort_extensions(Path(p), args.ignore)
if __name__ == "__main__":
_sort_extensions()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment