You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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解析库,能自动处理带引号的字段、空列等情况,完美适配动态列数:

  1. 先安装包:
npm install papaparse
  1. 编写去重代码:
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组合:

  1. 安装依赖:
npm install csv-parser csv-stringify
  1. 编写代码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:02:48