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

如何用Perl或PowerShell对比CSV文件,仅提取新增Name行?

解决方案:提取CSV中新增的Name行

你的需求是只获取File2中存在但File1中没有的Name对应的整行,而不是所有文本差异行——原来的Text::Diff是逐行文本对比,所以会把内容变更的行也列出来,这不符合你的要求。下面分别用Perl和PowerShell实现更精准的基于Name列的筛选:

方法一:用Perl实现(推荐使用Text::CSV处理CSV)

直接基于Name列的存在性对比比文本逐行对比更可靠,尤其是CSV可能包含复杂字段(比如字段内有逗号)。我们可以用Text::CSV模块来正确解析CSV,避免手动处理引号和逗号的麻烦:

Perl代码

#!/usr/bin/env perl
use strict;
use warnings;
use Text::CSV;

# 初始化CSV解析器,处理带引号的字段
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });

# 读取File1的所有Name到哈希表,用于快速查找
my %existing_names;
open my $f1_fh, '<', $ARGV[0] or die "无法打开File1: $!";
# 跳过表头
$csv->getline($f1_fh);
while (my $row = $csv->getline($f1_fh)) {
    my $name = $row->[0]; # Name是第一列
    $existing_names{$name} = 1;
}
close $f1_fh;

# 遍历File2,输出Name不在File1中的行
open my $f2_fh, '<', $ARGV[1] or die "无法打开File2: $!";
# 先输出表头(如果需要的话)
my $header = $csv->getline($f2_fh);
$csv->print(\*STDOUT, $header);
print "\n";

while (my $row = $csv->getline($f2_fh)) {
    my $name = $row->[0];
    unless (exists $existing_names{$name}) {
        $csv->print(\*STDOUT, $row);
        print "\n";
    }
}
close $f2_fh;

调用方式

和之前一样,通过bat或者直接命令行调用,输出到Diff.csv:

perl "C:\diffBetweenTwoFiles.pl" "C:\File1.csv" "C:\File2.csv" > "C:\Diff.csv"

如果不想安装Text::CSV模块(虽然强烈推荐),也可以用正则提取Name字段,但要注意仅适用于Name字段格式统一的情况:

#!/usr/bin/env perl
use strict;
use warnings;

my %existing_names;
open my $f1_fh, '<', $ARGV[0] or die "无法打开File1: $!";
<$f1_fh>; # 跳过表头
while (<$f1_fh>) {
    if (/^"([^"]+)"/) { # 提取第一个带引号的字段作为Name
        $existing_names{$1} = 1;
    }
}
close $f1_fh;

open my $f2_fh, '<', $ARGV[1] or die "无法打开File2: $!";
print scalar <$f2_fh>; # 输出表头
while (<$f2_fh>) {
    if (/^"([^"]+)"/ && !exists $existing_names{$1}) {
        print $_;
    }
}
close $f2_fh;

方法二:用PowerShell实现

PowerShell处理CSV非常便捷,不需要额外安装模块,直接用内置命令即可:

PowerShell命令

# 读取两个CSV文件
$file1 = Import-Csv -Path "C:\File1.csv"
$file2 = Import-Csv -Path "C:\File2.csv"

# 筛选File2中Name不在File1里的行,导出到Diff.csv
$file2 | Where-Object { $file1.Name -notcontains $_.Name } | Export-Csv -Path "C:\Diff.csv" -NoTypeInformation

说明

  • Import-Csv会自动解析CSV的表头和字段,不需要手动处理引号。
  • -NoTypeInformation参数避免在导出的CSV开头添加PowerShell的类型信息(比如#TYPE System.Management.Automation.PSCustomObject)。
  • 如果要通过bat调用PowerShell,可以写如下bat脚本:
    powershell -Command "$file1 = Import-Csv 'C:\File1.csv'; $file2 = Import-Csv 'C:\File2.csv'; $file2 | Where-Object { $file1.Name -notcontains $_.Name } | Export-Csv 'C:\Diff.csv' -NoTypeInformation"
    

内容的提问来源于stack exchange,提问作者faujong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:04:54