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
- āØļø CLI
- š Examples and recipes - CLI
- š Node API
- š Examples and recipes - Node
- š Benchmarks
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
frs-replace <regex> <replacement> [options]
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) |
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 underi-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 |
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
<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>
@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 |
Note: While all of examples are using synchronous API method in all cases your can use
async
as well.
import { sync } from '@frsource/frs-replace';
const result = sync({
input: 'foo.js',
regex: new RegExp('a', 'g'),
replacement: 'b',
output: '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',
});
Tested on Node v20.11.1.
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% |
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% |