Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pavlobu/20a9806b2e5c60d0d4cae851f8ab13dc to your computer and use it in GitHub Desktop.
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
/**
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