Skip to content

The fastest way to replace any text/file/piped stream content. Shipped with both NodeJS API & CLI out of the box!

License

Notifications You must be signed in to change notification settings

FRSOURCE/frs-replace

Repository files navigation

@frsource/frs-replace

NPM version badge GZIP size calculated by bundlejs.com semantic-release badge license MIT badge

NPM version badge semantic-release Coverage Status codebeat badge

The fastest (see benchmarks) CLI & Node wrapper around javascript replace which allows in-file replacing (with possibility to save changed file as a copy), globbing, piping and many more!

šŸ“œ Installation

npm install @frsource/frs-replace
yarn add @frsource/frs-replace
pnpm install @frsource/frs-replace

or execute it right away:

npx @frsource/frs-replace
yarn dlx @frsource/frs-replace
pnpx @frsource/frs-replace

āŒØļø CLI

frs-replace <regex> <replacement> [options]

Positionals

Option Type Description
<regex> string First parameter to RegExp constructor
<replacement> string String or path to replacement function file (see ā€‘ā€‘replaceā€‘fn switch for details)

Options

Note: Every boolean option can be negated with use of --no- prefix, e.g. --stdout or --no-stdout turn stdout output on or off, respectively.

Note: Object types can be set using dot notation. So, e.g. if you want to pass utf8 value under i-read-opts encoding field you should write --i-read-opts.encoding utf8.

Option Type Default Description
ā€‘i, ā€‘ā€‘input string or string[] - Path to files or fast-glob pattern pointing to files to be read & replaced from. If multiple files specified results will be joined using outputJoinString option's value)
ā€‘ā€‘i-read-opts string or object utf8 Options which are passed directly to the readFileSync method when reading input file
ā€‘ā€‘i-glob-opts object undefined Options which are passed directly to the fast-glob package when resolving glob patterns
ā€‘ā€‘stdin boolean true Wait for stdin input (should be set to false when used in non-interactive terminals)
ā€‘o, ā€‘ā€‘output string - Output file name/path (replaces the file if it already exists and creates any intermediate directories if they don't already exist)
ā€‘ā€‘o-write-opts string or object utf8 Passed as options argument of write's .sync
ā€‘ā€‘o-join-str string \n Used when joining multiple files, passed directly to javascript join
ā€‘c, ā€‘ā€‘content string - Content to be replaced (takes precedence over stream & file input)
ā€‘s, ā€‘ā€‘strategy "join" or "flatten" or "preserve-structure" "join" Output file generation strategy. "join" - joins all input files and outputs them as a single file using path passed as: "output". "preserve-structure" - saves all files to the "output" directory keeping relative directory structure."flatten" - same as "preserve-structure" but flattens the directory structure
ā€‘f, ā€‘ā€‘flags combination of gim flags g RegExp flags
ā€‘ā€‘stdout boolean true if piped input present, false otherwise Force sending output on stdout
ā€‘r, ā€‘ā€‘replaceā€‘fn boolean false Treat replacement argument as path to file containing replacement function
ā€‘h, ā€‘ā€‘help boolean - Show help
ā€‘v, ā€‘ā€‘version boolean - Show version number

šŸ”Ž Examples and recipes - CLI

1. Replace all a occurrences with b from the foo.js file and return the result (using CLI)

frs-replace a b -i foo.js --stdout

2. Replace all a occurrences with b from foo.js and save the result to the foo_replaced.js (using CLI)

frs-replace a b -i foo.js -o foo_replaced.js

3. Replace all a occurrences with b from an array of files and save the result to the foo_replaced.js using default \n as a result-joining string (using CLI)

frs-replace a b -i foo.js -i foo2.js -o foo_replaced.js

4. Replace all a occurrences with b from all .js files in the foo directory and save the result to the foo_replaced.js using \n/////\n as a result-joining string (using CLI)

frs-replace a b -i foo/*.js -o foo_replaced.js --o-join-str "\n/////\n"

5. Replace all a occurrences with b in a content string abcd and save the result to the foo_replaced.js (using CLI)

frs-replace a b --content abcd -o foo_replaced.js

6. Replace all a occurrences with b from a piped stream and save it to the output file (using CLI)

<read-file> | frs-replace a b > <output-file-path>

7. Replace all a occurrences with b from a piped stream and pass it through the stdout stream to the <next-command> (using CLI)

<read-file> | frs-replace a b | <next-command>

šŸ“š Node API

@frsource/frs-replace package is shipped in 2 flavors: synchronous and asynchronous:

import { sync, async } from '@frsource/frs-replace';

sync({
  /* options */
});
async({
  /* options */
});

Where /* options */ is an object containing:

Note: one of parameters: input or content is required

Option Type Default Description
input string or string[] undefined Path to files or fast-glob pattern pointing to files to be read & replaced from. If multiple files specified results will be joined using outputJoinString option's value)
inputReadOptions string or object utf8 Options which are passed directly to the readFileSync method when reading input file
inputGlobOptions object undefined Options which are passed directly to the fast-glob package when resolving glob patterns
content string undefined Content to be replaced (takes precedence over file input)
strategy "join" or "flatten" or "preserve-structure" "join" Output file generation strategy. "join" - joins all input files and outputs them as a single file using path passed as: "output". "preserve-structure" - saves all files to the "output" directory keeping relative directory structure."flatten" - same as "preserve-structure" but flattens the directory structure
needle string or RegExp Object - Used as a first argument of javascript replace
replacement string - Passed as a second argument to javascript replace
output string undefined Path of an output file
outputWriteOptions string or object "utf8" Passed as options argument of write's .sync
outputJoinString string \n String used when joining multiple files, passed directly to javascript join

šŸ”Ž Examples and recipes - Node

Note: While all of examples are using synchronous API method in all cases your can use async as well.

1. Replace all a occurrences with b from the foo.js file and return the result

import { sync } from '@frsource/frs-replace';

const result = sync({
  input: 'foo.js',
  regex: new RegExp('a', 'g'),
  replacement: 'b',
  output: 'foo_replaced.js',
});

2. Replace all a occurrences with b from foo.js and save the result to the foo_replaced.js

import { sync } from '@frsource/frs-replace';
const result = sync({
  input: 'foo.js',
  regex: new RegExp('a', 'g'),
  replacement: 'b',
  output: 'foo_replaced.js',
});

3. Replace all a occurrences with b from an array of files and save the result to the foo_replaced.js using default \n as a result-joining string

import { sync } from '@frsource/frs-replace';
const result = sync({
  input: ['foo.js', 'foo2.js'],
  regex: new RegExp('a', 'g'),
  replacement: 'b',
  output: 'foo_replaced.js',
});

4. Replace all a occurrences with b from all .js files in the foo directory and save the result to the foo_replaced.js using \n/////\n as a result-joining string

import { sync } from '@frsource/frs-replace';
const result = sync({
  input: 'foo/*.js',
  regex: new RegExp('a', 'g'),
  replacement: 'b',
  outputJoinString: '\n/////\n',
  output: 'foo_replaced.js',
});

5. Replace all a occurrences with b in a content string abcd and save the result to the foo_replaced.js

import { sync } from '@frsource/frs-replace';
const result = sync({
  content: 'abcd',
  regex: new RegExp('a', 'g'),
  replacement: 'b',
  output: 'foo_replaced.js',
});

šŸ“ˆ Benchmarks

Tested on Node v20.11.1.

input as glob pattern [40 files]

Rank Library Average latency [ms] Difference percentage (comparingĀ toĀ bestĀ averageĀ latency)
1 @frsource/frs-replace (async) 0.63 Ā± 1.16% +0.00%
2 @frsource/frs-replace (sync) 0.72 Ā± 1.41% +13.30%
3 replace-in-file (async) 1.04 Ā± 3.68% +63.87%
4 replace-in-file (async) 1.40 Ā± 9.58% +122.24%

input & replacement as strings

Rank Library Average latency [ms] Difference percentage (comparingĀ toĀ bestĀ averageĀ latency)
1 @frsource/frs-replace (sync) 0.01 Ā± 0.39% +0.00%
2 @frsource/frs-replace (async) 0.01 Ā± 3.04% +20.92%
3 replaceString 0.03 Ā± 0.76% +509.71%