Last active
October 6, 2022 22:01
-
-
Save pavlobu/20a9806b2e5c60d0d4cae851f8ab13dc to your computer and use it in GitHub Desktop.
Node.js | A Script that replaces matching strings in text files of a .zip file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
A Script that replaces matching strings in text files of a .zip file | |
Dependencies: | |
npm i extract-zip | |
npm i zip-local | |
Usage: | |
The script can be run as 'node run nodejs-replace-matching-strings-in-text-files-of-a-zip.js' | |
Configuration: | |
The variables of this script can be replaced: | |
Variables: | |
- dir : a relative path along the current working directory. | |
The content of 'dir' should be a SINGE zip file that contains text files in it | |
Example usage: | |
|--nodejs-replace-matching-strings-in-text-files-of-a-zip.js | |
|--some | |
|--|--dir | |
|--|--|--some.zip | |
Here the content of 'some/dir' is only 1 'some.zip' file: | |
so the value of 'dir' should be: | |
const dir = 'some/dir'; | |
- filesToReplaceInZip : the files where string replacement should occur in target zip | |
Example usage: | |
suppose that our 'some/dir/some.zip' has following structure when unzipped: | |
|--stuff | |
|--|--text3.txt | |
|--text2.txt | |
|--text1.txt | |
And we want some strings to be replaced in these files: | |
stuff/text3.txt | |
text1.txt | |
Then the value of 'filesToReplaceInZip' should be set like this: | |
const filesToReplaceInZip = [ | |
'stuff/text3.txt', | |
'text1.txt' | |
]; | |
- stringsToReplace : an array of objects. Each object has: | |
* oldVal - the string that should be replaced | |
* newVal - the string that the will be replaced with | |
Example usage: | |
In our target files we want | |
1. this string occurence: 'old_string' to be replaced with 'NEW_string' | |
2. this string occurence: 'second_old_string' to be replaced with 'second_NEW_string' | |
Then the value of 'stringsToReplace' should be like this: | |
const stringsToReplace = [ | |
{ oldVal: 'old_string', newVal: 'NEW_string'}, | |
{ oldVal: 'second_old_string'', newVal: 'second_NEW_string'} | |
]; | |
*/ | |
const dir = 'some/dir'; | |
const filesToReplaceInZip = [ | |
'stuff/text3.txt', | |
'text1.txt' | |
]; | |
const stringsToReplace = [ | |
{ oldVal: 'old_string', newVal: 'NEW_string'}, | |
{ oldVal: 'second_old_string', newVal: 'second_NEW_string'} | |
]; | |
const fs = require('fs'); | |
const { promises: { readFile: fsReadFile, writeFile: fsWriteFile } } = require('fs'); | |
const path = require('path'); | |
const extract = require('extract-zip') | |
const zipper = require('zip-local'); | |
fs.readdir(path.join(...dir.split('/')), async(err, files) => { | |
if (err) { | |
throw err | |
} | |
const zipFiles = files.filter((file) => file.endsWith('.zip')); | |
const dropZip = path.resolve(path.join(dir, zipFiles[0])); | |
const dropDir = dropZip.replace('.zip', ''); | |
await extract(dropZip, { dir: path.resolve(path.join(dropDir)) }); | |
fs.unlinkSync(dropZip); | |
for (let i = 0; i < filesToReplaceInZip.length; i+=1) { | |
const file = filesToReplaceInZip[i]; | |
const sourceFile = path.resolve(path.join(dropDir, path.join(...file.split('/')))); | |
await fsReadFile(sourceFile, { encoding: 'utf8' }).then(async (data) => { | |
let result = data.toString(); | |
for (let i = 0; i < stringsToReplace.length; i+=1) { | |
const { oldVal: oldValue, newVal: newValue } = stringsToReplace[i]; | |
result = result.replaceAll(oldValue, newValue); | |
} | |
await fsWriteFile(sourceFile, result, 'utf8') | |
}); | |
} | |
await zipper.sync.zip(dropDir).compress().save(dropZip); | |
fs.rmSync(dropDir, { recursive: true, force: true }); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment