Windows CMD / BATCH命令 - FC命令显示匹配的上/下行

5
我想使用cmd.exe的fc命令来比较两个文本文件。但是,它也会打印不匹配行上面和下面的行。我该如何抑制这种行为? a.txt
32=10500.3000000
31=5252.8095
30=XXXX
75=20170208 00:32:40
6=5252.8095
60=20170208-00:00:03
b.txt
32=10500.3000000
31=5252.8095
30=YYYY
75=20170208 00:32:40
6=5252.8095
60=20170208-00:00:03
命令 - fc /l /n /c /t /lb200 a.txt b.txt1 输出 正在比较文件a.txt和B.TXT
***** a.txt
    2:  31=5252.8095
    3:  30=XXXX
    4:  75=20170208 00:32:40
***** B.TXT
    2:  31=5252.8095
    3:  30=YYYY
    4:  75=20170208 00:32:40
*****
我想要的
***** a.txt
    3:  30=XXXX
***** B.TXT
    3:  30=YYYY
*****

这是不可能的,除非在命令周围使用 for /f 循环或第三方实用程序。 - Sam Denty
用for循环逐行比较? - Pankaj Jaju
for /f loop to remove the first line before and after every occurrence of ***** - Sam Denty
1
只要存在仅有一个不同行数的单一块,您可以使用 for /F 搜索 ***** 行并删除其中相等的行,或者依靠行号进行同步并使用 for /F;但是,一旦文件内的行相对于另一个文件添加/移动/删除,或者存在多个不同的块,则无法可靠地使用 for /F 删除匹配的 fc 行... - aschipfl
1
请查看FComp.bat:该批处理程序将FC输出重新排列,使其更易于阅读。该程序识别原始文件两行之间添加的新部分、从原始文件中删除的部分或以任何其他方式修改(更新)的部分,并以一种允许您轻松识别每种情况的格式显示它们。 - Aacini
3个回答

2
您可以将此作为起点。
@echo off
    setlocal enableextensions disabledelayedexpansion

    for /f "tokens=1,* delims=: eol=*" %%a in ('
        fc /l /n /t /c 1.txt 2.txt 
    ') do (
        if defined _%%a (
            set "line=%%b"
            setlocal enabledelayedexpansion
            if not !_%%a!==!line! (
                echo(%%a: !_%%a!
                echo(%%a: !line!
                echo(
            )
            endlocal
            set "_%%a="
        ) else set "_%%a=%%b"
    )

在处理fc命令的输出时,为每个行号定义一个变量。当找到相同的行号时,将比较变量的内容和新行的内容,如果它们不同,则会回显这两行。


谢谢。我确实尝试过类似的方法,但这是一种非常硬编码的解决方法。如果文本文件中缺少或添加了行,我将错过这些差异。 - Pankaj Jaju
1
@PankajJaju,你是对的,fc非常有限,这段代码只是继承了它的局限性。无论如何,对于小范围的差异,fc应该足够了。 - MC ND
@MCND 有没有一种方法可以使此脚本将新行和旧行分开?换句话说,第二个文件中存在但不在第一个文件中的任何行都会进入文件new.txt,而第一个文件中存在但不在第二个文件中的任何行都会进入old.txt - Mark Deven

1
即使与所选标签无关,我仍然建议使用诸如windiff或WinMerge之类的工具进行并排比较。还可以参见Gui-diff-tools。一些编辑器也提供了类似的选项,例如TextPad。 Winmerge

使用WinMerge,选择菜单中的“工具”->“生成补丁”,完成! - Count Boxer

0

很遗憾,fc 命令 的输出格式无法按您的要求进行配置。

以下脚本只是简单地搜索以 ***** 开头的行,并跳过每个这样的行之前或之后的行,除了第一行,它永远不会被跳过。当然,在许多情况下,这种方法可能会失败,但对于简单的不同块,只要 fc 能够同步(因此必须为 /LB 选项指定足够的数字),它应该可以正常工作:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem /* Initialise variables, then loop over output of `fc` command,
rem    with all command line arguments simply forwarded to `fc`: */
set "LINE=" & set "PREV=" & for /F "delims=" %%L in ('fc %*') do (
    rem // This query is needed to skip lines after `*****`:
    if not defined PREV (
        rem /* This is just to not skip the very first line; just
        rem    comment it out if you do want to skip this line: */
        if not defined LINE echo(%%L
        rem // Store current line for next loop iteration:
        set "PREV=%%L"
    ) else (
        rem // Store current line:
        set "LINE=%%L"
        setlocal EnableDelayedExpansion
        rem // Check if current line begins with `*****`:
        if "!LINE:~,5!" == "*****" (
            rem // Return current line but not the previous one:
            echo(!LINE!
            endlocal
            set "PREV=%%L"
        ) else (
            rem /* Current line does not begin with `*****`,
            rem    so check whether previous line does: */
            if "!PREV:~,5!" == "*****" (
                endlocal
                rem /* Previous line begins with `*****`, hence
                rem    clear buffer for previous line in order to
                rem    let the following line be skipped then: */
                set "PREV="
            ) else (
                rem /* Neither the current nor the previous lines
                rem    begin with `*****`, so return the latter: */
                echo(!PREV!
                endlocal
                set "PREV=%%L"
            )
        )
    )
)

endlocal
exit /B

假设你的脚本名字叫做filecomp.bat,只需要像调用fc命令一样带上所有参数来调用它,例如:
filecomp.bat /L /N /C /T /LB200 "a.txt" "b.txt"

根据您提供的示例数据,假设批处理文件和示例数据文件都位于当前工作目录中,则输出将如下所示:

Comparing files a.txt and B.TXT
***** a.txt
    3:  30=XXXX
***** B.TXT
    3:  30=YYYY
*****

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接