如何使用Node.js去除CSV文件中的重复行
去除CSV重复行的简便方法与Node.js方案
针对你需要处理动态列数CSV去重的需求,这里有两种实用方案,不管是快速命令行操作还是Node.js代码实现都能搞定:
一、快速命令行方法(无需写代码)
如果你只是想快速处理文件,用awk命令就能搞定,它能正确处理带引号的CSV内容,且不关心列数变化:
awk -F '"' '!seen[$0]++' input.csv > output.csv
这个命令的逻辑很简单:逐行读取CSV,把整行内容作为唯一标识存入seen数组,只保留第一次出现的行,最终结果写入output.csv。
二、Node.js代码实现(灵活可控)
如果需要集成到你的Node.js项目里,推荐用成熟的CSV处理包,下面给两个常用方案:
方案1:使用papaparse(推荐,处理CSV场景更全面)
papaparse是一个轻量且强大的CSV解析库,能自动处理带引号的字段、空列等情况,完美适配动态列数:
- 先安装包:
npm install papaparse
- 编写去重代码:
const fs = require('fs'); const Papa = require('papaparse'); const inputFile = './input.csv'; const outputFile = './output.csv'; const seenRows = new Set(); let csvHeader = []; // 流式读取CSV,避免大文件内存溢出 fs.createReadStream(inputFile) .pipe(Papa.parse(Papa.NODE_STREAM_INPUT, { header: false })) .on('data', (row) => { // 保存表头,只写入一次 if (csvHeader.length === 0) { csvHeader = row; return; } // 将整行转为JSON字符串作为唯一标识,适配动态列数 const rowKey = JSON.stringify(row); if (!seenRows.has(rowKey)) { seenRows.add(rowKey); // 追加写入去重后的行 fs.appendFileSync(outputFile, Papa.unparse([row]) + '\n'); } }) .on('end', () => { // 最后把表头写入文件开头 fs.writeFileSync(outputFile, Papa.unparse([csvHeader]) + '\n', { flag: 'r+' }); console.log(`去重完成!结果已保存到 ${outputFile}`); });
方案2:使用csv工具包(流式处理更高效)
如果你需要更底层的流式控制,可以用csv-parser和csv-stringify组合:
- 安装依赖:
npm install csv-parser csv-stringify
- 编写代码:
const fs = require('fs'); const csvParser = require('csv-parser'); const csvStringify = require('csv-stringify'); const inputFile = './input.csv'; const outputFile = './output.csv'; const seenRows = new Set(); const outputStream = fs.createWriteStream(outputFile); let stringifier; let isFirstRow = true; fs.createReadStream(inputFile) .pipe(csvParser({ headers: false })) .on('data', (row) => { if (isFirstRow) { // 初始化字符串化器,匹配表头列数 stringifier = csvStringify({ header: false }); stringifier.pipe(outputStream); stringifier.write(row); isFirstRow = false; return; } // 用列值拼接成唯一键(如果列值包含|,可以换成\x00这类特殊字符) const rowKey = Object.values(row).join('|'); if (!seenRows.has(rowKey)) { seenRows.add(rowKey); stringifier.write(row); } }) .on('end', () => { stringifier.end(); console.log('CSV去重完成!'); });
注意事项
- 处理大文件时,优先选择流式处理的方案(上面的代码都是流式),避免一次性加载整个文件导致内存溢出。
- 不要手动分割CSV行(比如用
split(',')),因为字段里可能包含逗号(被引号包裹),手动分割会破坏数据结构,一定要用专业的CSV解析库。
内容的提问来源于stack exchange,提问作者hweiu321
相关产品推荐
相关产品推荐

