如何使用node-csv解析器跳过文件的第一行?

时间:2014-01-10 09:37:00

标签: node.js csv

目前我正在使用node-csv(http://www.adaltas.com/projects/node-csv/)进行csv文件解析。

在开始解析数据之前,有没有办法跳过文件的前几行?例如,有些csv报告在实际标题和数据开始之前的前几行中有报告详细信息。

LOG REPORT                  <- data about the report
DATE: 1.1.1900
DATE,EVENT,MESSAGE          <- data headers
1.1.1900,LOG,Hello World!   <- actual data stars here

3 个答案:

答案 0 :(得分:5)

这里有两个选项:

  1. 您可以逐行处理文件。我之前在answer发布了一个代码段。你可以用那个

    var rl = readline.createInterface({
        input: instream,
        output: outstream,
        terminal: false
    });
    
    rl.on('line', function(line) {
        console.log(line);
        //Do your stuff ...
        //Then write to outstream
        rl.write(line);
    });
    
  2. 您可以为文件流提供一个偏移量,该偏移量将跳过这些字节。您可以在documentation

    中查看
    fs.createReadStream('sample.txt', {start: 90, end: 99});
    

    如果您知道偏移是固定的,这会容易得多。

答案 1 :(得分:5)

假设您使用v0.4或更高版本使用新的重构(即csv-generate,csv-parse,stream-transform和csv-stringify),您可以使用内置转换跳过第一行,还有一些额外的工作。

var fs = require('fs'),
    csv = require('csv');

var skipHeader = true; // config option

var read = fs.createReadStream('in.csv'),
    write = fs.createWriteStream('out.jsonish'),
    parse = csv.parse(),
    rowCount = 0, // to keep track of where we are
    transform = csv.transform(function(row,cb) {
        var result;
        if ( skipHeader && rowCount === 0 ) { // if the option is turned on and this is the first line
            result = null; // pass null to cb to skip
        } else {
            result = JSON.stringify(row)+'\n'; // otherwise apply the transform however you want
        }
        rowCount++; // next time we're not at the first line anymore
        cb(null,result); // let node-csv know we're done transforming
    });

read
    .pipe(parse)
    .pipe(transform)
    .pipe(write).once('finish',function() {
        // done
    });

基本上我们跟踪已经转换的行数,如果我们是第一个(我们实际上希望通过skipHeader bool跳过标题),那么通过{{ 1}}回调作为第二个参数(第一个总是错误),否则传递转换后的结果。

这也适用于同步解析,但需要更改,因为在同步模式下没有回调。此外,相同的逻辑可以应用于旧的v0.2库,因为它还内置了行转换。

请参阅http://csv.adaltas.com/transform/#skipping-and-creating-records

这很容易应用,而IMO的占地面积非常小。通常,您希望跟踪为状态目的而处理的行,并且我几乎总是在将结果集发送到Writable之前对其进行转换,因此只需添加额外的逻辑来检查跳过标题是非常简单的。这里的额外好处是我们使用相同的模块来应用跳过逻辑,就像我们要解析/转换一样 - 不需要额外的依赖。

答案 2 :(得分:1)

{from_line: 2}函数内部传递参数parse()所需做的所有事情。 就像下面的

const fs = require('fs');
const parse = require('csv-parse');

fs.createReadStream('path/to/file')
    .pipe(parse({ delimiter: ',', from_line: 2 }))
    .on('data', (row) => {
        // it will start from 2nd row
        console.log(row)
    })