我有两个文本文件,我该如何比较它们?基本上我所追求的是从文本文件 1 中取出第一行并将其与文本文件 2 中的所有行进行比较的东西,如果该行没有出现,则将该行写入文本文件 3。
然后检查文本文件 1 中的下一行与文本文件 2 中的所有行,依此类推。
我有两个文本文件,我该如何比较它们?基本上我所追求的是从文本文件 1 中取出第一行并将其与文本文件 2 中的所有行进行比较的东西,如果该行没有出现,则将该行写入文本文件 3。
然后检查文本文件 1 中的下一行与文本文件 2 中的所有行,依此类推。
如果您有一份适用于 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 解决方案,但这不是我的专长。