PAYATHON 2026

如何使用 Windows FC 命令只比较文本文件中的指定部分?

技术老齐

FC 没有参数可以只比较指定列、指定字符范围,或忽略某个字段之后的内容。可以先从两份文件中提取需要比较的部分,再用 fc.exe 比较提取结果。

为什么现有参数解决不了

FC 按行比较文本,行内的时间和日期也会参与比较。

/W 处理空格和制表符差异,/C 忽略大小写,/A 缩短差异输出。这些参数都不能排除时间戳字段。/nnnn 指定的是发现差异后重新同步所需的连续匹配行数,并非要比较的列数。具体说明见 Microsoft 的 FC 文档。

固定长度:提取每行前 10 个字符

示例中的 Data 12345 恰好有 10 个字符。如果关键内容始终在第 1~10 列,可以先截取这部分。

假设两个文件名为 File_A.txt 和 File_n.txt,在文件所在目录打开 PowerShell,执行:

Get-Content -LiteralPath '.\File_A.txt' -Encoding UTF8 -ErrorAction Stop |
    ForEach-Object { $_.Substring(0, [Math]::Min(10, $_.Length)) } |
    Set-Content -LiteralPath '.\A.prefix.txt' -Encoding Unicode -ErrorAction Stop

Get-Content -LiteralPath '.\File_n.txt' -Encoding UTF8 -ErrorAction Stop |
    ForEach-Object { $_.Substring(0, [Math]::Min(10, $_.Length)) } |
    Set-Content -LiteralPath '.\B.prefix.txt' -Encoding Unicode -ErrorAction Stop

fc.exe /u '.\A.prefix.txt' '.\B.prefix.txt'

题目中的两行经过提取后,两个中间文件都会包含:

Data 12345

这样,时间和日期的变化就不会影响比较结果。如果关键内容变成 Data 54321,提取结果也会改变,FC 仍会报告差异。

Substring() 的起始索引从 0 开始;[Math]::Min() 用来避免在处理不足 10 个字符的短行时越界。

长度可变:按 Time 字段截取

如果数字的位数可能变化,固定取前 10 个字符会漏掉差异。例如,Data 123456 和 Data 123457 的前 10 个字符相同,最后一位的差异会在截取时丢失。

如果格式始终是“关键内容 + 空格 + Time + 空格 + 时间戳”,可以把上述两处 ForEach-Object 都替换为:

ForEach-Object { $_ -creplace ' Time .*$', '' }

这条规则会删除第一个 Time 及其后面的全部内容,保留完整的关键字段。例如:

Data 123456 Time 3:15 PM Date May 3 2026

处理后得到:

Data 123456

-creplace 区分大小写,标记必须恰好为 Time。没有这个标记的行保持原样。使用前应确认关键内容本身不会出现同样的标记。

使用时注意

  • 示例按 UTF-8 读取原文件。如果文件采用其他编码,需要调整 Get-Content 的 -Encoding,避免解码错误影响比较结果。
  • 中间文件使用 -Encoding Unicode 写成 UTF-16LE,因此要配合 fc.exe /u 比较。该编码的含义见 Set-Content 文档。
  • A.prefix.txt 和 B.prefix.txt 是中间文件,重复执行会覆盖它们,原文件不会被修改。
  • 多行文件会逐行提取,再按原有顺序交给 FC 比较。比较通过只表示提取后的内容一致。
  • 在 PowerShell 中应写 fc.exe,避免 fc 被解析为 Format-Custom 的别名。执行后可立即查看 $LASTEXITCODE:0 表示一致,1 表示不同,2 表示比较出错。

备注:内容仅供参考。