-2

我有两个文本文件,我该如何比较它们?基本上我所追求的是从文本文件 1 中取出第一行并将其与文本文件 2 中的所有行进行比较的东西,如果该行没有出现,则将该行写入文本文件 3。

然后检查文本文件 1 中的下一行与文本文件 2 中的所有行,依此类推。

4

1 回答 1

1

如果您有一份适用于 Windows 的 grep 副本,那么问题就很简单了。一个很好的免费资源是GnuWin您可以从软件包链接下载单个实用程序,例如 grep ,或者您可以使用全部下载链接(单击该页面开头的下载按钮)获取整个 GnuWin 套件。

grep -v -x -F -f file2.txt file1.txt >file3.txt

-v= 反转匹配逻辑 - 列出不匹配的行

-x= 整行必须完全匹配

-F= 搜索字符串是字符串文字而不是正则表达式

-f file1.txt= 从 file1.txt 中获取搜索字符串


您几乎可以使用本机 FINDSTR 命令做同样的事情,除了有 2 个问题:

1) 搜索字符串中的任何反斜杠字符\都必须转义为\\,即使在指定文字搜索时也是如此。

2) 如果使用多个区分大小写的文字搜索字符串,则存在一个令人讨厌的 FINDSTR 错误,该错误会导致丢失某些匹配项。

请参阅Windows FINDSTR 命令有哪些未记录的功能和限制?获取未记录的 FINDSTR 问题的“完整”列表。

只要可以进行不区分大小写的搜索并且 file2 不包含任何\字符,则以下内容将起作用:

findstr /x /v /i /l /g:file2.txt file1.txt >file3.txt

可以通过创建一个转义反斜杠的临时文件来消除反斜杠限制。这是一些代码,但最终结果仍然运行得相当快。搜索仍然必须不区分大小写。

@echo off
setlocal disableDelayedExpansion

::Define the files
set "file1=test1.txt"
set "file2=test2.txt"
set "file3=test3.txt"

::Create an LF variable containing a line feed character
set LF=^


::The above 2 blank lines are critical - do not remove

::Create a modified version of file2 that escapes any backslash
::EOL is set to a linefeed so that all non blank lines are preserved
::Delayed expansion is toggled on and off to protect ! characters
>"%file2%.mod" (
  for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file2%") do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    echo(!ln:\=\\!
    endlocal
  )
)

::Find lines in file1 that are missing from file2.mod
findstr /vixlg:"%file2%.mod" "%file1%" >"%file3%"

::Delete the temporary file2.mod
del "%file2%.mod"

使用 2 个 FOR 循环编写一个健壮的本机批处理解决方案相对简单,但如果文件很大,性能会迅速下降。

@echo off
setlocal disableDelayedExpansion

::Define the files
set "file1=test2.txt"
set "file2=test.txt"
set "file3=test3.txt"

::Create an LF variable containing a line feed character
set LF=^


::The above 2 blank lines are critical - do not remove

::Find lines in file1 that are missing from file2.mod
::EOL is set to a linefeed character so that all non blank lines are preserved
>"%file3%" (
  for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file1%") do (
    set "found="
    for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%B in ("%file2%") do (
      if %%A==%%B set found=1
    )
    if not defined found echo %%A
  )
)


可能有一个简单高效的原生 PowerShell 解决方案,但这不是我的专长。

于 2012-09-10T17:13:33.260 回答