目前我正在使用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
答案 0 :(得分:5)
这里有两个选项:
您可以逐行处理文件。我之前在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);
});
您可以为文件流提供一个偏移量,该偏移量将跳过这些字节。您可以在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)
})