Skip to main content

A CLI utility for replacing multi-line strings in files. Supports textual replacements with wildcard matching indentation-aware replacements.

Project description

Multi-Line Replacer (mlr)

Copyright 2025 Caleb Evans
Released under the MIT license

tests Coverage Status

Multi-Line Replacer is a CLI utility for replacing multi-line hunks of strings across one or more files. Matching is mostly textual, but wildcard matching is supported, and replacements are indentation-aware.

Usage

The workflow takes one or more files on which to run replacements, and then a series of "replacement rule" files with the -r flag:

mlr .github/workflows/*.yml -r example-rules/uv-gha.md

Each replacement rule must be a Markdown file with one or more pairs of GFM fenced code blocks (see documentation). Every odd code block represents the target text to replace, and every even code block represents the textual replacement. All other Markdown formatting is ignored, so feel free to add headings, explainer text, or anything else!

This rule replaces flake8 with ruff in a Github Actions linting workflow.

## flake8

```yml
- name: Run flake8
  run: flake8 MATCH_UNTIL_END_OF_LINE
```

## ruff

```yml
- name: Run ruff
  run: |
    uv run ruff check .
    uv run ruff format --check .
```

[!NOTE] The language specifier at the start of each code fence is ignored by the utility. Still, it is highly recommended to specify so that syntax highlighting is enabled in your editor (i.e. it's for you, not the tool).

Wildcard Matching

There are two special wildcard variables:

  • MATCH_UNTIL_END_OF_LINE ([^\n]*)
  • MATCH_ALL_BETWEEN ([^\n]*?)

These variables can be used anywhere in any code block representing the target text to match. Because these names are unique enough, word boundaries are not required around them (e.g. vMATCH_UNTIL_END_OF_LINE is allowed).

More Examples

To better understand the expected rules format and what's allowed, please see the example-rules directory.

About

Multi-Line Replacer was built as my solution to an intermediate need I had while writing a large migration script. I had 17 Python projects using old tooling, and the script was written to migrate these projects to uv and ruff.

Part of this migration process necessitated performing textual replacements on multi-line hunks of code. Regular expressions and editors like VS Code could somewhat achieve this, although they required escaping special characters and carefully specifying indentation. In other words, those tools proved to be too rigid and inflexible.

Given these constraints, I conceived of a utility that could perform multi-line replacements with a friendlier authoring experience and greater indentation awareness. The implementation took several iterations to achieve positive results, but by the end, it contributed significantly to the successful migration of all 17 projects. From there, I decided to release it to the world as a more flexible and automated system for replacing multi-line hunks of code.

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

multi_line_replacer-1.0.0b4.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

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

multi_line_replacer-1.0.0b4-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file multi_line_replacer-1.0.0b4.tar.gz.

File metadata

File hashes

Hashes for multi_line_replacer-1.0.0b4.tar.gz
Algorithm Hash digest
SHA256 10e95626ad9b06ec92c943a1b7f42a07eb7d54adbcba7ea42aac10e8fdfb4375
MD5 96ff8a8b918d95bb0629142a2e80cf88
BLAKE2b-256 794f35359498a45c739c050ef14ecbecf44be19d38efb151e153ee994a73f044

See more details on using hashes here.

File details

Details for the file multi_line_replacer-1.0.0b4-py3-none-any.whl.

File metadata

File hashes

Hashes for multi_line_replacer-1.0.0b4-py3-none-any.whl
Algorithm Hash digest
SHA256 3c2a93a63f49821d8121991bbffe76b3df44eede82b305aaad03ccf708a45de6
MD5 1f8114bf42161287f96a57220a7a9e0d
BLAKE2b-256 e2772d8ae79f85d056bf673fda8825d21bd9172b0f9b7bddec4c7751d29be04b

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