在批处理脚本中比较两个文件

0 batch-file file-comparison

我试图以这种方式比较两个文件,文件1的每一行将与文件2的每一行进行比较,如果没有找到匹配,则将该行写入单独的文件.

下面是我写的代码,但它没有按预期工作,

@echo on
cd path
for /f %%a in (file1.txt) do (
for /f %%b in (file2.txt) do (
if %%a==%%b
(
echo lines are same
) else (
echo %%a >> file3.txt
)
)
)
Run Code Online (Sandbox Code Playgroud)

我收到一个错误说,命令的语法不正确.请帮我解决一下这个.

dbe*_*ham 5

foxidrive显示的FINDSTR方法肯定是解决问题的最快的纯批处理方法,特别是如果file2很大.但是,有许多方案可能导致其失败:文件1中的正则表达式元文件,文件1中的引号和/或反斜杠等.请参阅Windows FINDSTR命令的未记录的功能和限制是什么?对于所有潜在的问题.更多的工作可以使解决方案更可靠.

  • 搜索应该明确地用文字表示
  • 搜索应该完全匹配(整行)
  • 搜索行中的任何反斜杠都应该转义为 \\
  • 每次搜索都应存储在临时文件中并使用该\G:file选项

另外,您没有描述每一行的格式.你FOR/F报表将只读,因为默认的每一行的第一个字delims的选择<tab><space>.我怀疑你想要delims什么都没有.您还要禁用该eol选项,以便;不跳过以行开头的行.这需要一些奇怪的语法.我添加了该usebackq选项,以防您处理必须引用的文件名.

@echo off
setlocal disableDelayedExpansion
set "file1=file1.txt"
set "file2=file2.txt"
set "file3=file3.txt"
set "search=%temp%\search.txt"

>"%file3%" (
  for /f usebackq^ delims^=^ eol^= %%A in ("%file1%") do if "%%A" neq "" (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    (echo(!ln:\=\\!) >"%search%"
    findstr /lxg:"%search%" "%file2%" >nul || (echo(!ln!)
    endlocal
  )
)
del "%search%" 2>nul
Run Code Online (Sandbox Code Playgroud)

如果你的file2不包含\"并且你可以负担不区分大小写的搜索,那么有一个非常快的单行解决方案:只需反转FINDSTR搜索以查找file1中文件2中不存在的任何行.搜索必须是不区分大小写因为为什么这个带有多个文字搜索字符串的FINDSTR示例找不到匹配项?.

findstr /livxg:"file2.txt" "file1.txt" >"file3.txt"
Run Code Online (Sandbox Code Playgroud)

如果file2包含\"因转义问题,这将无效.您可以预处理file2并将其全部转义\,但如果您将自己限制为纯批处理解决方案,那么您也可以使用第一个解决方案.

如果您愿意使用名为REPL.BAT混合JScript /批处理实用程序,那么我有一个非常简单有效的解决方案.REPL.BAT对stdin的每一行执行正则表达式搜索和替换操作,并将结果写入stdout.

假设REPL.BAT位于您当前的目录中,或者更好,位于您的路径中的某个位置:

@echo off
setlocal
set "file1=file1.txt"
set "file2=file2.txt"
set "file3=file3.txt"
set "search=%temp%\search.txt"

type "%file2%"|repl \\ \\ >"%search%"
findstr /livxg:"%search%" "%file1%" >"%file3%"
del "%search%" 2>nul
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方案仍必须执行不区分大小写的比较.