Node.js How to delete first line in file

Here is streamed version of removing first line from file.
As it uses streams, means you don't need to load whole file in memory, so it is way more efficient and fast, as well can work on very large files without filling memory on your hardware.

var Transform = require('stream').Transform;
var util = require('util');


// Transform sctreamer to remove first line
function RemoveFirstLine(args) {
    if (! (this instanceof RemoveFirstLine)) {
        return new RemoveFirstLine(args);
    }
    Transform.call(this, args);
    this._buff = '';
    this._removed = false;
}
util.inherits(RemoveFirstLine, Transform);

RemoveFirstLine.prototype._transform = function(chunk, encoding, done) {
    if (this._removed) { // if already removed
        this.push(chunk); // just push through buffer
    } else {
        // collect string into buffer
        this._buff += chunk.toString();

        // check if string has newline symbol
        if (this._buff.indexOf('\n') !== -1) {
            // push to stream skipping first line
            this.push(this._buff.slice(this._buff.indexOf('\n') + 2));
            // clear string buffer
            this._buff = null;
            // mark as removed
            this._removed = true;
        }
    }
    done();
};

And use it like so:

var fs = require('fs');

var input = fs.createReadStream('test.txt'); // read file
var output = fs.createWriteStream('test_.txt'); // write file

input // take input
.pipe(RemoveFirstLine()) // pipe through line remover
.pipe(output); // save to file

Another way, which is not recommended.
If your files are not large, and you don't mind loading them into memory, load file, remove line, save file, but it is slower and wont work well on large files.

var fs = require('fs');

var filePath = './test.txt'; // path to file

fs.readFile(filePath, function(err, data) { // read file to memory
    if (!err) {
        data = data.toString(); // stringify buffer
        var position = data.toString().indexOf('\n'); // find position of new line element
        if (position != -1) { // if new line element found
            data = data.substr(position + 1); // subtract string based on first line length

            fs.writeFile(filePath, data, function(err) { // write file
                if (err) { // if error, report
                    console.log (err);
                }
            });
        } else {
            console.log('no lines found');
        }
    } else {
        console.log(err);
    }
});

Thanks to @Lilleman 's comment, I've made an amendment to the original solution, which requires a 3rd-party module "line-by-line" and can prevent memory overflow and racing condition while processing very large file.

const fs = require('fs');
const LineReader = require('line-by-line');

const removeLines = function(srcPath, destPath, count, cb) {

  if(count <= 0) {
    return cb();
  }

  var reader = new LineReader(srcPath);
  var output = fs.createWriteStream(destPath);

  var linesRemoved = 0;
  var isFirstLine = true;

  reader.on('line', (line) => {
    if(linesRemoved < count) {
      linesRemoved++;
      return;
    }
    reader.pause();

    var newLine;
    if(isFirstLine) {
      newLine = line;
      isFirstLine = false;
    } else {
      newLine = '\n' + line;
    }

    output.write(newLine, () => {
      reader.resume();
    });
  })
  .on('error', (err) => {
    reader.pause();
    return cb(err);
  })
  .on('close', () => {
    return cb();
  })
}

---------------- original solution below---------------

Inspired by another answer, here is a revised stream version:

const fs = require('fs');
const readline = require('readline');

const removeFirstLine = function(srcPath, destPath, done) {

  var rl = readline.createInterface({
    input: fs.createReadStream(srcPath)
  });
  var output = fs.createWriteStream(destPath);
  var firstRemoved = false;

  rl.on('line', (line) => {
    if(!firstRemoved) {
      firstRemoved = true;
      return;
    }
    output.write(line + '\n');
  }).on('close', () => {
    return done();
  })
}

and it can be easily modified to remove certain amount of lines, by changing the 'firstRemoved' into a counter:

var linesRemoved = 0;
...
if(linesRemoved < LINES_TO_BE_REMOVED) {
  linesRemoved++;
  return;
}
...

Here is another way:

const fs = require('fs');
const filePath = './table.csv';

let csvContent = fs.readFileSync(filePath).toString().split('\n'); // read file and convert to array by line break
csvContent.shift(); // remove the the first element from array
csvContent = csvContent.join('\n'); // convert array back to string

fs.writeFileSync(filePath, csvContent);

Tags:

File

Line

Node.Js