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

如何用标准Unix命令按1:1匹配找出文件的异同行?

用标准Unix命令实现1:1匹配的文件行对比需求

需求说明

现有两个文本文件,需要完成以下三类行的识别:

  • (a) 两文件共有的行(要求1:1匹配:文件1的一行只能匹配文件2的一行,不能一个文件的一行对应另一个文件的多行)
  • (b) 仅存在于第一个文件的行
  • (c) 仅存在于第二个文件的行

常规方法如cat+uniq、comm或fgrep无法满足这种1:1的匹配规则,以下是具体示例:

示例文件内容

File 1

A
B
C
A
B
C

File 2

A
B
A
D

预期输出结果

Common in both: A, B, A
In file 1 only: C, B, C
In file 2 only: D

解决方案:使用awk实现

可以用awk脚本实现这种精确的1:1匹配逻辑,脚本代码如下:

BEGIN {
    OFS = ", "
}
# 遍历第一个文件,统计每行出现次数
NR == FNR {
    cnt1[$0]++
    next
}
# 遍历第二个文件,匹配公共行并更新计数
{
    if (cnt1[$0] > 0) {
        cnt1[$0]--
        common[++c_idx] = $0
    } else {
        only_file2[++f2_idx] = $0
    }
}
# 处理剩余行并输出结果
END {
    # 收集文件1中未匹配的行
    for (line in cnt1) {
        for (i=1; i<=cnt1[line]; i++) {
            only_file1[++f1_idx] = line
        }
    }
    # 输出公共行
    printf "Common in both: "
    for (i=1; i<=c_idx; i++) {
        printf "%s%s", common[i], (i == c_idx ? "\n" : OFS)
    }
    # 输出仅文件1的行
    printf "In file 1 only: "
    for (i=1; i<=f1_idx; i++) {
        printf "%s%s", only_file1[i], (i == f1_idx ? "\n" : OFS)
    }
    # 输出仅文件2的行
    printf "In file 2 only: "
    for (i=1; i<=f2_idx; i++) {
        printf "%s%s", only_file2[i], (i == f2_idx ? "\n" : OFS)
    }
}

使用方法

  1. 将上述代码保存为match_lines.awk
  2. 在终端执行命令:
awk -f match_lines.awk file1 file2

逻辑说明

  • 首先遍历第一个文件,用数组cnt1记录每行的出现次数
  • 遍历第二个文件时,若当前行在cnt1中还有剩余计数,就将其归入公共行列表,并减少对应计数;否则归入仅文件2的行列表
  • 最后遍历cnt1数组,将剩余有计数的行按次数归入仅文件1的行列表
  • 最终按要求格式输出三类结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:32:44