import argparse
import os
import re
import sys
parser = argparse.ArgumentParser()
# add required arguments
parser.add_argument("regex", type=str, help="match against filenames")
parser.add_argument("replacement", type=str, help="replaces matches with this")
parser.add_argument("filenames", nargs="*", help="filenames to be changed")
# add some optional boolean arguments
parser.add_argument(
"-d", "--dryrun", action="store_true", help="show changes but don't make them"
)
parser.add_argument(
"-v", "--verbose", action="store_true", help="print more information"
)
parser.add_argument(
"-e",
"--eval",
action="store_true",
help="evaluate replacement as python expression, match available as _",
)
# optional integer argument which defaults to 1
parser.add_argument(
"-n",
"--replace_n_matches",
type=int,
default=1,
help="replace n matches (0 for all matches)",
)
args = parser.parse_args()
def eval_replacement(match):
"""if --eval given, evaluate replacment string as Python
with the variable _ set to the matching part of the filename
"""
if not args.eval:
return args.replacement
_ = match.group(0)
return str(eval(args.replacement))
for old_pathname in args.filenames:
try:
new_pathname = re.sub(
args.regex, eval_replacement, old_pathname, count=args.replace_n_matches
)
except OSError as e:
print(
f"{sys.argv[0]}: '{old_pathname}': '{args.replacement}' {e}",
file=sys.stderr,
)
continue
if new_pathname == old_pathname:
if args.verbose:
print("no change:", old_pathname)
continue
if os.path.exists(new_pathname):
print(f"{sys.argv[0]}: '{new_pathname}' exists", file=sys.stderr)
continue
if args.dryrun:
print(old_pathname, "would be renamed to", new_pathname)
continue
if args.verbose:
print("'renaming", old_pathname, "to", new_pathname)
try:
os.rename(old_pathname, new_pathname)
except OSError as e:
print(f"{sys.argv[0]}: '{new_pathname}' {e}", file=sys.stderr)
Print the last number (real or integer) on every line
Note: regexp to match number: -?\d+\.?\d*
Note: use of assignment operator :=