A regex file renamer/mover
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Correcting structure

Summer ec994560 29326729

+59 -56
+55
multimv/__init__.py
··· 1 + #!/usr/bin/env python3 2 + from argparse import ArgumentParser, Namespace 3 + from pathlib import Path 4 + import shlex 5 + 6 + def main(): 7 + parser = ArgumentParser() 8 + parser.add_argument("-m", "--method", choices=["re"], default="re") 9 + parser.add_argument("-g", "--global", dest="global_", action="store_true") 10 + parser.add_argument("-i", "--ignore-case", action="store_true") 11 + parser.add_argument("-d", "--dry-run", action="store_true") 12 + parser.add_argument("-q", "--quiet", action="store_true") 13 + parser.add_argument("pattern") 14 + parser.add_argument("replacement") 15 + parser.add_argument("files", nargs="*", type=Path) 16 + args = parser.parse_args() 17 + 18 + 19 + # Per method code 20 + if args.method == "re": 21 + import re 22 + 23 + def new_path(old): 24 + return old.with_name( 25 + re.sub( 26 + args.pattern, 27 + repl=args.replacement, 28 + string=old.name, 29 + flags=(re.I if args.ignore_case else 0), 30 + count=(0 if args.global_ else 1), 31 + ) 32 + ) 33 + 34 + 35 + # Generic code 36 + moves = [] 37 + for old in args.files: 38 + if old != (new := new_path(old)): 39 + moves.append(Namespace(old=old, new=new)) 40 + 41 + if any(m.new.exists() for m in moves): 42 + raise Error # Collides with pre-existing file 43 + 44 + if len({m.new for m in moves}) < len(moves): 45 + raise Error # List has duplicates 46 + 47 + for move in moves: 48 + if not args.quiet: 49 + print( 50 + f"- {shlex.quote(str(move.old))}", 51 + f"+ {shlex.quote(str(move.new))}", 52 + sep="\n", 53 + ) 54 + if not args.dry_run: 55 + move.old.rename(move.new)
-55
multimv/__main__.py
··· 1 - #!/usr/bin/env python3 2 - from argparse import ArgumentParser, Namespace 3 - from pathlib import Path 4 - import shlex 5 - 6 - 7 - parser = ArgumentParser() 8 - parser.add_argument("-m", "--method", choices=["re"], default="re") 9 - parser.add_argument("-g", "--global", dest="global_", action="store_true") 10 - parser.add_argument("-i", "--ignore-case", action="store_true") 11 - parser.add_argument("-d", "--dry-run", action="store_true") 12 - parser.add_argument("-q", "--quiet", action="store_true") 13 - parser.add_argument("pattern") 14 - parser.add_argument("replacement") 15 - parser.add_argument("files", nargs="*", type=Path) 16 - args = parser.parse_args() 17 - 18 - 19 - # Per method code 20 - if args.method == "re": 21 - import re 22 - 23 - def new_path(old): 24 - return old.with_name( 25 - re.sub( 26 - args.pattern, 27 - repl=args.replacement, 28 - string=old.name, 29 - flags=(re.I if args.ignore_case else 0), 30 - count=(0 if args.global_ else 1), 31 - ) 32 - ) 33 - 34 - 35 - # Generic code 36 - moves = [] 37 - for old in args.files: 38 - if old != (new := new_path(old)): 39 - moves.append(Namespace(old=old, new=new)) 40 - 41 - if any(m.new.exists() for m in moves): 42 - raise Error # Collides with pre-existing file 43 - 44 - if len({m.new for m in moves}) < len(moves): 45 - raise Error # List has duplicates 46 - 47 - for move in moves: 48 - if not args.quiet: 49 - print( 50 - f"- {shlex.quote(str(move.old))}", 51 - f"+ {shlex.quote(str(move.new))}", 52 - sep="\n", 53 - ) 54 - if not args.dry_run: 55 - move.old.rename(move.new)
+4 -1
pyproject.toml
··· 1 1 [tool.poetry] 2 2 name = "multimv" 3 - version = "0.1.0" 3 + version = "0.2.0" 4 4 description = "Multi mv via fixed string / regex / bash pattern substitutions" 5 5 authors = ["Summer"] 6 6 license = "MIT" 7 7 8 8 [tool.poetry.dependencies] 9 9 python = "^3.6" 10 + 11 + [tool.poetry.scripts] 12 + multimv = 'multimv:main' 10 13 11 14 [build-system] 12 15 requires = ["poetry-core>=1.0.0"]