Skip to main content

Because one mv is rarely enough

Project description

mvs: Because one mv is rarely enough

Motivation

Renaming a bunch of files and directories can be tedious, error-prone work. Command-line tools to perform such tasks are numerous. Perhaps the most classic example was the Perl rename script, which has been available or installable on most Unix-inspired operating systems since the early 1990s.

The core idea of rename was excellent. The user supplied a snippet of Perl code as a command-line argument, followed by the original paths. Each original path was pumped through the code snippet to generate the corresponding new path. Because Perl was designed to make it easy to manipulate strings with very little code, users could efficiently rename paths directly on the command line. Even if you hardly knew Perl but at least understood how to operate its compact regular-expression substitution syntax, you could become quite adept at bulk path renaming.

$ rename 's/foo/bar/' *

Unfortunately, the script was a chainsaw – undeniably useful, but able to inflict devastation after a single false move. As a result, I rarely used rename directly for my bulk renaming needs, which were extensive on several projects I worked on. Instead, I wrote my own Perl script to do the job. Its operation was roughly the same, but it included precautions to help me avoid disastrous mistakes. The most important were checking that the new paths did not collide with existing paths on the file system and including an inspection and confirmation step by default.

The mvs library is an updated and enhanced version of those ideas, but implemented in a language I use regularly (Python) rather than one in which I have become rusty (Perl).

The mvs executable

The primary use case envisioned for the library is its executable. In broad terms, there are two ways to perform bulk renaming with the mvs command: (1) the user provides original file paths and a snippet of Python code to perform the original-to-new computation, or (2) the user provides both original paths and new paths directly.

Either way, before any renaming occurs, mvs checks for common problems that might occur in bulk renaming scenarios, provides an informative listing of the proposed renamings grouping them into meaningful categories based on those checks, and waits for user confirmation before attempting any renamings. In addition, the script logs detailed information about the renamings to support the user in the event that they later regret what they have done.

The script provides various command-line options to customize its behavior, supports user preferences, and provides detailed documentation on policy, process, listings, input path structures, user-supplied code, problem checking, configuration, logging, and caveats.

Installation and examples

Install the library in the usual way.

$ pip install mvs

Get usage help and detailed documentation.

$ mvs --help
$ mvs --details

A simple example:

$ mvs a b --rename 'return f"{o}.new"'

Programmatic usage

The mvs package also supports bulk renaming via a programmatic API. This can be done by creating a RenamingPlan instance and then calling its rename_paths() method. Initialization parameters and their defaults are as follows.

from mvs import RenamingPlan

plan = RenamingPlan(
    # Sequence of paths and their structure.
    inputs,
    structure = 'flat',

    # User-supplied renaming and filtering code (str or callable).
    # See mvs --details for additional information.
    rename_code = None,
    filter_code = None,

    # Other parameters related to user-supplied code.
    indent = 4,
    seq_start = 1,
    seq_step = 1,

    # Additional rigor in the face of problems.
    # See mvs --details.
    skip = None,
    strict = None,
)

plan.rename_paths()

If you do not want to rename paths immediately but do want to prepare everything for renaming, including performing the checks for problems, you can use the library in a more deliberative fashion: first prepare; then check the information provided by the plan; if desired, proceed with renaming; and in the event of unexpected failure, get information about which item led to the exception.

# The library's supported imports.
from mvs import RenamingPlan, MvsError, __version__

# Configure plan.
plan = RenamingPlan(...)

# Prepare for renaming.
plan.prepare()

# All relevant information about the plan and its renamings.
print(plan.as_dict)

# Whether preparation failed.
print(plan.failed)

# The renamings organized into four groups:
# - filtered out by user code;
# - excluded, due to unresolvable problems;
# - skipped, due to resolvable problems configured by user an ineligible;
# - active renamings.
print(plan.filtered)
print(plan.excluded)
print(plan.skipped)
print(plan.active)

# Try to rename.
try:
    plan.rename_paths()
except Exception as e:
    # The index of the active Renaming that was being handled
    # when the exception occurred. Renamings before that index were
    # renamed succesfully; renamings after it were not attempted.
    i = plan.tracking_index
    print(i)

    # Two ways to see the offending renaming.
    print(plan.tracking_rn)
    print(plan.active[i])

    # Renamings that were performed.
    print(plan.active[:i])

    # Renamings that were not attempted.
    print(plan.active[i + 1:])

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mvs-2.0.0.tar.gz (53.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mvs-2.0.0-py3-none-any.whl (35.8 kB view details)

Uploaded Python 3

File details

Details for the file mvs-2.0.0.tar.gz.

File metadata

  • Download URL: mvs-2.0.0.tar.gz
  • Upload date:
  • Size: 53.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.4

File hashes

Hashes for mvs-2.0.0.tar.gz
Algorithm Hash digest
SHA256 5545a471a8dd2df1bed8a5142f4b6aea0b2fdbccd7a9d5e07f98b9878962c0b2
MD5 4a947ba6a717e57e63fda22830e3a218
BLAKE2b-256 b9257f0cd9ac57c073d34accd42c2feed9fa3abb10f70b3986a91149afe9ea48

See more details on using hashes here.

File details

Details for the file mvs-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: mvs-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 35.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.4

File hashes

Hashes for mvs-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ecc97fb769f96b35d7c3a0b787972e36a7849422dd90a804566ab729eec80dd8
MD5 066f19a4dbed356bab4873e8894b1df1
BLAKE2b-256 96ddbe8cbd1f14ebec6f8fafda93bd906d1a2780acf810effd48a9cc36d83e66

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page