Git Product home page Git Product logo

multi-sub's Introduction

multi-sub

Build multi-sub Status

Substitute a pattern with a replacement on specific lines

By default, sed's s/.../.../ command tries to perform a substitution on all lines in a file. Sometimes that is too coarse grained. By contrast, multi-sub limits the substitution to only happen on specified lines.

multi-sub takes input that looks like

filename.txt:17
filename.txt:42
another.md:12
another.md:23

and substitutes some pattern with some replacement only on the lines specified in the input. The replacement is always done in place. In this way, multi-sub is a Unix-style pipeline sink.

If sed is like a chainsaw, multi-sub is more like a scalpel. Using a combination of tools like git grep -l and awk with multi-sub, we can construct precise filters. Specifically, two other tools are particularly useful in conjunection with multi-sub:

  • diff-locs is a tool that converts a unified diff into input suitable for multi-sub.

  • multi-grep is like multi-sub, but with grep.

multi-sub is fast. It's implemented in OCaml, compiled with OCaml's impressive optimizing compiler, and has been repeatedly profiled to improve performance. It only does work that's absolutely needed.

Usage

This is the help for multi-sub version 0.0.0. It might be out of date—run multi-sub --help locally for up-to-date help.

❯ multi-sub --help
Usage:
  multi-sub [options] <pattern> <replace> [<locs.txt>]

Substitutes the pattern with the replacement in the mentioned lines.

Arguments:
  <pattern>      A valid OCaml regular expression[1].
  <replace>      The expression to substitute when a match is found[2].
  <locs.txt>     The name of a file with lines formatted like:
                   filename.ext:20
                 If omitted, reads from stdin.

Options:
  -i, --ignore-case     Treat the pattern as case insensitive.
  -s, --case-sensitive  Treat the pattern as case sensitive [default].
  -g, --global          Replace all matches on a line, not just the first.
  --version             Print version and exit.

[1]: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Str.html#VALregexp
[2]: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Str.html#VALglobal_replace

Install

There are pre-compiled binaries for macOS and Linux. You can also install from source (see Contributing).

macOS

Using Homebrew:

  • brew install jez/formulae/multi-sub

Or, download the binary directly from the releases:

Linux

Download the binary from the releases page:

Contributing

One-time setup

  1. Make sure you have opam installed. OPAM manages both the OCaml compiler version and any OCaml packages' versions.

    → How to install opam

    The next instructions assume you're using opam 2.0+ (opam --version).

  2. Create a switch for this project:

    ❯ git clone https://github.com/jez/multi-sub
    ❯ cd multi-sub
    ❯ opam switch create . ocaml-base-compiler.4.07.1
  3. Install dune:

    ❯ opam install dune

Building

# To build for development:
❯ dune build

# To run:
❯ dune exec -- multi-sub

# To install from source:
❯ dune install --prefix="$HOME/.local"

TODO

  • Add test suite
    • Test that we preserve permissions
    • Document how to run and add tests
    • Test for out-of-order input lines
    • Test for options (-g, -i, -s)
    • Test that missing arguments gives error
    • Test that we don't add a trailing newline if the file doesn't have one
  • Publish Homebrew formula
    • Document how to bump the version
  • Set up ShellCheck
  • Set up source code formatter
  • Document how to set up editor tools

License

MIT License

multi-sub's People

Contributors

jez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

multi-sub's Issues

Bug

Input

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.5
BuildVersion:	18F132
$ multi-sub --version
0.2.0
$ cat input.txt
A
$ echo 'input.txt:1' | multi-sub 'A' 'BBBBB'
$ cat input.txt
BBBBB
BBB

Expected output

$ cat input.txt
BBBBB

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.