Skip to content

Instantly share code, notes, and snippets.

@dclowd9901
Last active December 21, 2015 20:09
Show Gist options
  • Save dclowd9901/6359098 to your computer and use it in GitHub Desktop.
Save dclowd9901/6359098 to your computer and use it in GitHub Desktop.
Accepts a js file containing a JSON-compliant array of filenames and looks through each file for comma-separated terms. The result is a list of files that contain references to the terms.
/**
*
* ManyFilesGrepper.js
* Accepts a js file containing a JSON-compliant array of
* filenames and looks through each file for comma-separated terms.
* The result is a list of files that contain references to
* the terms.
*
* Usage:
* >node ManyFilesGrepper.js path/to/list/of/files.js terms,to,match [path/to/file/to/write/to.js]
*/
var fs = require('fs'),
_ = require('/usr/local/lib/node_modules/lodash'),
q = require('/usr/local/lib/node_modules/q'),
listFile = process.cwd() + '/' + process.argv[2],
terms = process.argv[3].split(','),
outputFile = process.argv[4] ? process.cwd() + '/' + process.argv[4] : undefined;
fs.readFile(listFile, 'utf8', function (err, data) {
var list = JSON.parse(data);
var mfg = new ManyFilesGrepper(list, terms, outputFile);
});
var ManyFilesGrepper = function (list, terms, outputFile) {
var _list = list,
_terms = terms,
_outputFile = outputFile;
var returnable = {
init : function () {
this.process();
},
process: function () {
var self = this,
filesGotten = [];
_.forEach(_list, function (filePath) {
filesGotten.push(self.getFileData(filePath));
});
q.all(filesGotten)
.then(this.addUpMatchOutputs.bind(this))
.then(this.writeToFile.bind(this));
},
/**
* Promise adapter for standard readFile
* @param {string} filePath Path to file
*/
getFileData: function (filePath) {
var def = q.defer();
fs.readFile(filePath, 'utf8', function (err, data) {
def.resolve({data: data, filePath: filePath});
});
return def.promise;
},
/**
* Cycle through returned array of file contents
* and summate the cases where instances were found
* @param {array} dataArr Q.all() generated array of values (from array of promises)
*/
addUpMatchOutputs: function (dataArr) {
var combinedText,
self = this;
combinedText = _.reduce(dataArr, function (output, data) {
return output + self.outputMatchesForFile(data.filePath, self.matchTerms(data.data));
});
return combinedText;
},
/**
* Convenience method for matching multiple terms
* in a file.
* @param {string} fileData File data to search through.
*/
matchTerms: function (fileData) {
var i,
matching = {},
matchingLine;
for (i = 0; i < _terms.length; i++) {
matchingLine = this.matchTerm(fileData, _terms[i]);
if (_.size(matchingLine)) {
matching[_terms[i]] = _.cloneDeep(matchingLine);
}
}
return matching;
},
/**
* Find terms in a body of text, and return their line
* numbers as well as the line they exist on.
* @param {string} fileData File data to search through.
* @param {string} term String to match.
*/
matchTerm: function (fileData, term) {
var fileDataArr = this.splitTextIntoArrayOfLines(fileData),
matchingLines = {};
_.forEach(fileDataArr, function (line, key) {
if (line.indexOf(term) > -1) {
matchingLines[key] = line;
}
});
return matchingLines;
},
/**
* Cycle through returned array of file contents
* and summate the cases where instances were found
* @param {string} dataArr Q.all() generated array of values (from array of promises)
*/
outputMatchesForFile: function (filePath, matches) {
var text = '';
text += '\nMatches in:' + filePath + '\n\n';
_.forEach(matches, function (match, term) {
_.forEach(match, function (line, number) {
text += number + '[' + term + ']:' + line + '\n';
});
});
return text;
},
/**
* Write results to a file or output in console, depending on existence of argument.
* @param {string} text Body of text to write.
*/
writeToFile: function (text) {
if (_outputFile) {
fs.writeFile(_outputFile, text, function (err) {
console.log('Saved in ' + _outputFile);
});
} else {
console.log(text);
}
},
/**
* Breaks multiline text into
* @param {string} fileData File data to search through.
* @param {string} term String to match.
*/
splitTextIntoArrayOfLines: function (text) {
return text ? text.split('\n') : undefined;
}
};
returnable.init();
return returnable;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment