Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A simple utility to quickly replace contents in one or more files

NotificationsYou must be signed in to change notification settings

adamreisnz/replace-in-file

Repository files navigation

npm versioncoverage statusgithub issues

A simple utility to quickly replace text in one or more files or globs. Works synchronously or asynchronously with either promises or callbacks. Make a single replacement or multiple replacements at once.

Index

Installation

# Using npmnpm i replace-in-file# Using yarnyarn add replace-in-file

Asynchronous replacement

import{replaceInFile}from'replace-in-file'constoptions={files:'path/to/file',from:/foo/g,to:'bar',}try{constresults=awaitreplaceInFile(options)console.log('Replacement results:',results)}catch(error){console.error('Error occurred:',error)}

Synchronous replacement

import{replaceInFileSync}from'replace-in-file'constoptions={files:'path/to/file',from:/foo/g,to:'bar',}try{constresults=replaceInFileSync(options)console.log('Replacement results:',results)}catch(error){console.error('Error occurred:',error)}

Return value

The return value of the library is an array of replacement results against each file that was processed. This includes files in which no replacements were made.

Each result contains the following values:

  • file: The path to the file that was processed
  • hasChanged: Flag to indicate if the file was changed or not
constresults=replaceInFileSync({files:'path/to/files/*.html',from:/foo/g,to:'bar',})console.log(results)// [//   {//     file: 'path/to/files/file1.html',//     hasChanged: true,//   },//   {//     file: 'path/to/files/file2.html',//     hasChanged: true,//   },//   {//     file: 'path/to/files/file3.html',//     hasChanged: false,//   },// ]

To get an array of changed files, simply map the results as follows:

constchangedFiles=results.filter(result=>result.hasChanged).map(result=>result.file)

Counting matches and replacements

By setting thecountMatches configuration flag totrue, the number of matches and replacements per file will be counted and present in the results array.

  • numMatches: Indicates the number of times a match was found in the file
  • numReplacements: Indicates the number of times a replacement was made in the file

Note that the number of matches can be higher than the number of replacements if a match and replacement are the same string.

constresults=replaceInFileSync({files:'path/to/files/*.html',from:/foo/g,to:'bar',countMatches:true,})console.log(results)// [//   {//     file: 'path/to/files/file1.html',//     hasChanged: true,//     numMatches: 3,//     numReplacements: 3,//   },//   {//     file: 'path/to/files/file2.html',//     hasChanged: true,//     numMatches: 1,//     numReplacements: 1,//   },//   {//     file: 'path/to/files/file3.html',//     hasChanged: false,//     numMatches: 0,//     numReplacements: 0,//   },// ]

Advanced usage

Replace a single file or glob

constoptions={files:'path/to/file',}

Replace multiple files or globs

constoptions={files:['path/to/file','path/to/other/file','path/to/files/*.html','another/**/*.path',],}

Replace first occurrence only

constoptions={from:'foo',to:'bar',}

Replace all occurrences

Please note that the value specified in thefrom parameter is passed straight to the nativeString replace method. As such, if you pass a string as thefrom parameter, it willonly replace the first occurrence.

To replace multiple occurrences at once, you must use a regular expression for thefrom parameter with the global flag enabled, e.g./foo/g.

constoptions={from:/foo/g,to:'bar',}

Multiple values with the same replacement

These will be replaced sequentially.

constoptions={from:[/foo/g,/baz/g],to:'bar',}

Multiple values with different replacements

These will be replaced sequentially.

constoptions={from:[/foo/g,/baz/g],to:['bar','bax'],}

Multiple replacements with different options

There is no direct API in this package to make multiple replacements on different files with different options. However, you can easily accomplish this in your scripts as follows:

constreplacements=[{files:'path/to/file1',from:/foo/g,to:'bar',},{files:'path/to/file2',from:/bar/g,to:'foo',}]awaitPromise.all(replacements.map(options=>replaceInFile(options)))

Custom regular expressions

Use theRegExp constructor to create any regular expression.

conststr='foo'constregex=newRegExp('^'+str+'bar','i')constoptions={from:regex,to:'bar',}

Using callbacks forfrom

You can also specify a callback that returns a string or a regular expression. The callback receives the name of the file in which the replacement is being performed, thereby allowing the user to tailor the search string. The following example uses a callback to produce a search string dependent on the filename:

constoptions={files:'path/to/file',from:(file)=>newRegExp(file,'g'),to:'bar',}

Using callbacks forto

As theto parameter is passed to the nativeString replace method, you can also specify a callback. The following example uses a callback to convert matching strings to lowercase:

constoptions={files:'path/to/file',from:/SomePattern[A-Za-z-]+/g,to:(match)=>match.toLowerCase(),}

This callback provides for an extra argument above the String replace method, which is the name of the file in which the replacement is being performed. The following example replaces the matched string with the filename:

constoptions={files:'path/to/file',from:/SomePattern[A-Za-z-]+/g,to:(...args)=>args.pop(),}

Saving to a different file

You can specify agetTargetFile config param to modify the target file for saving the new file contents to. For example:

constoptions={files:'path/to/files/*.html',getTargetFile:source=>`new/path/${source}`,from:'foo',to:'bar',}

Ignore a single file or glob

constoptions={ignore:'path/to/ignored/file',}

Ignore multiple files or globs

constoptions={ignore:['path/to/ignored/file','path/to/other/ignored_file','path/to/ignored_files/*.html','another/**/*.ignore',],}

Please note that there is anopen issue with Glob that causes ignored patterns to be ignored when using a./ prefix in your files glob. To work around this, simply remove the prefix, e.g. use**/* instead of./**/*.

Allow empty/invalid paths

If set to true, empty or invalid paths will fail silently and no error will be thrown. For asynchronous replacement only. Defaults tofalse.

constoptions={allowEmptyPaths:true,}

Disable globs

You can disable globs if needed using this flag. Use this when you run into issues with file paths like files like//SERVER/share/file.txt. Defaults tofalse.

constoptions={disableGlobs:true,}

Specify glob configuration

Specify configuration passed to theglob call:

constoptions={//Glob settings here (examples given below)glob:{//To include hidden files (starting with a dot)dot:true,//To fix paths on Windows OS when path.join() is used to create pathswindowsPathsNoEscape:true,},}

Please note that the settingnodir will always be passed asfalse.

Making replacements on network drives

To make replacements in files on network drives, you may need to specify the UNC path as thecwd config option. This will then be passed to glob and prefixed to your paths accordingly. See#56 for more details.

Specify character encoding

Use a different character encoding for reading/writing files. Defaults toutf-8.

constoptions={encoding:'utf8',}

Dry run

To do a dry run without actually making replacements, for testing purposes. Defaults tofalse.

constoptions={dry:true,}

Using custom processors

For advanced usage where complex processing is needed it's possible to use a callback that will receive content as an argument and should return it processed.

constresults=awaitreplaceInFile({files:'path/to/files/*.html',processor:(input)=>input.replace(/foo/g,'bar'),})

The custom processor will receive the path of the file being processed as a second parameter:

constresults=awaitreplaceInFile({files:'path/to/files/*.html',processor:(input,file)=>input.replace(/foo/g,file),})

This also supports passing an array of functions that will be executed sequentially

functionsomeProcessingA(input){constchapters=input.split('###')chapters[1]=chapters[1].replace(/foo/g,'bar')returnchapters.join('###')}functionsomeProcessingB(input){returninput.replace(/foo/g,'bar')}constresults=replaceInFileSync({files:'path/to/files/*.html',processor:[someProcessingA,someProcessingB],})

Alongside theprocessor, there is alsoprocessorAsync which is the equivalent for asynchronous processing. It should return a promise that resolves with the processed content:

constresults=awaitreplaceInFile({files:'path/to/files/*.html',processorAsync:async(input,file)=>{constasyncResult=awaitdoAsyncOperation(input,file);returninput.replace(/foo/g,asyncResult)},})

Using a custom file system API

replace-in-file defaults to using'node:fs/promises' and'node:fs' to provide file reading and write APIs.You can provide anfs orfsSync object of your own to switch to a different file system, such as a mock file system for unit tests.

  • For the asynchronous APIs, the providedfs must provide thereadFile andwriteFile methods.
  • For the synchronous APIs, the providedfsSync must provide thereadFileSync andwriteFileSync methods.

Customfs andfsSync implementations should have the same parameters and returned values as theirbuilt-in Nodefs equivalents.

replaceInFile({from:'a',fs:{readFile:async(file,encoding)=>{console.log(`Reading${file} with encoding${encoding}...`)return'fake file contents'},writeFile:async(file,newContents,encoding)=>{console.log(`Writing${file} with encoding${encoding}:${newContents}`)},},to:'b',})

Or for the sync API:

replaceInFileSync({from:'a',fsSync:{readFileSync:(file,encoding)=>{console.log(`Reading${file} with encoding${encoding}...`)return'fake file contents'},writeFileSync:(file,newContents,encoding)=>{console.log(`Writing${file} with encoding${encoding}:${newContents}`)},},to:'b',})

CLI usage

replace-in-file from to some/file.js,some/**/glob.js  [--configFile=config.json]  [--ignore=ignore/files.js,ignore/**/glob.js]  [--encoding=utf-8]  [--disableGlobs]  [--verbose]  [--quiet]  [--dry]

Multiple files or globs can be replaced by providing a comma separated list.

The flags--disableGlobs,--ignore and--encoding are supported in the CLI.

The settingallowEmptyPaths is not supported in the CLI as the replacement issynchronous, and this setting is only relevant for asynchronous replacement.

To list the changed files, use the--verbose flag. Success output can be suppressed by using the--quiet flag.

To do a dry run without making any actual changes, use--dry.

A regular expression may be used for thefrom parameter by passing in a string correctly formatted as a regular expression. The library will automatically detect that it is a regular expression.

Thefrom andto parameters, as well as the files list, can be omitted if you provide thisinformation in a configuration file.

You can provide a path to a configuration file(JSON) with the--configFile flag. This path will be resolved usingNode’s built inpath.resolve(), so you can pass in an absolute or relative path.

If you are using a configuration file, and you want to use a regular expression for thefrom value, ensure that it starts with a/, for example:

{"from":"/cat/g","to":"dog",}

A note on using globs with the CLI

When using the CLI, the glob pattern is handled by the operating system. But if you specify the glob pattern in the configuration file, the package will use the glob module from the Node modules, and this can lead to different behaviour despite using the same pattern.

For example, the following will only look at top level files:

{"from":"cat","to":"dog",}
replace-in-file**  --configFile=config.json

However, this example is recursive:

{"files":"**","from":"cat","to":"dog",}
replace-in-file --configFile=config.json

If you want to do a recursive file search as an argument you must use:

replace-in-file$(ls l {,**/}*)  --configFile=config.json

Version information

From version 8.0.0 onwards, this package requires Node 18 or higher. If you need support for older versions of Node, please use a previous version of this package.

As 8.0.0 was a significant rewrite, pleaseopen an issue if you run into any problems or unexpected behaviour.

See theChangelog for more information.

License

(MIT License)

Copyright 2015-2024, Adam Reis

About

A simple utility to quickly replace contents in one or more files

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp