Skip to content

Instantly share code, notes, and snippets.

@matths
Created May 7, 2014 09:10
Show Gist options
  • Save matths/7c0a1166067717a8e34a to your computer and use it in GitHub Desktop.
Save matths/7c0a1166067717a8e34a to your computer and use it in GitHub Desktop.
Line-by-line manipulation of text files (eg. error log files) using node.js' new Stream.Transform functionality and pipe(). You can call this directly from your shell, eg. $ node parse.js error.log
var fs = require('fs');
var TransformLine = require('./TransformLine');
// syntax example:
// $ node parse.js error.log
var inFile = process.argv[2];
var outFile = process.argv[3];
if (!inFile) {
console.log('no input file specified');
process.exit();
}
var inStream = fs.createReadStream(inFile);
var outStream = (!outFile) ? process.stdout : fs.createWriteStream(outFile, {flags: 'w'});
var createLineNumberTransformer = function() {
var i = 1;
return new TransformLine(function (line) {
return (i++)+': ' + line;
}, true);
};
var regexpTransformer = function(regexp, replaceString) {
return new TransformLine(function (line) {
var line = line.replace(regexp, replaceString);
return line ? line + '\n' : '';
});
};
// example how to remove lines containing '[debug]' from error.log files
var removeDebugMessageTransformer = regexpTransformer(/^.*\[debug\].*$/, '');
inStream
.pipe(removeDebugMessageTransformer)
.pipe(createLineNumberTransformer())
.pipe(outStream);
var util = require('util');
var Stream = require('stream');
var Transform = Stream.Transform;
function TransformLine(callback, addLineBreak) {
this._lineBreak = addLineBreak ? '\n' : '';
// allow use without new
if (!(this instanceof TransformLine)) {
return new TransformLine(callback);
}
Transform.call(this, {objectMode: true});
this._callback = callback;
}
util.inherits(TransformLine, Transform);
TransformLine.prototype._transform = function (chunk, encoding, done) {
var self = this;
var data = chunk.toString();
if (this._dataRemaining) {
data = this._dataRemaining + data;
}
var lines = data.split('\n');
this._dataRemaining = lines.splice(lines.length-1,1)[0];
lines.forEach(function(line) {
line = self._callback(line);
self.push(line + self._lineBreak);
});
done();
}
TransformLine.prototype._flush = function (done) {
var self = this;
if (this._dataRemaining) {
line = self._callback(_dataRemaining);
this.push(line + self._lineBreak);
}
this._dataRemaining = null;
done();
}
module.exports = TransformLine;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment