2013-10-07 113 views
0

我试图比较两个文件的方式,文件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 
) 
) 
) 

我得到一个错误的说法,该命令的语法不正确。 请帮我这个。

+1

为什么不使用'FC'命令? – npocmaka

+0

从帮助'IF /?'括号必须在同一行。 ''if %% a == %% b(' – jeb

+0

@npocmaka - FC命令不会给出OP的所需输出,它也是线序相关的,所以对这个问题完全不合适。 – dbenham

回答

3

语法错误是由错误放置的左圆括号引起的,但即使如此代码也无法按预期工作。

您比较file1中的每一行和file2的每一行,但是您会为每个不相等的比较输出结果,而不仅仅是在找不到匹配项时。

for /f %%a in (file1.txt) do (
    set "matchFound=" 
    for /f %%b in (file2.txt) do (
     if %%a==%%b (
      echo lines are same 
      set matchFound=1 
     ) 
    ) 

    if not defined matchFound (
     echo %%a is not found in file2 
    ) 
) 
1

给这个一展身手:

@echo on 
cd /d "c:\path" 
del file3.txt 2>nul 
for /f "delims=" %%a in (file1.txt) do (
    set "flag=" 
    for /f "delims=" %%b in (file2.txt) do (
     if "%%a"=="%%b" set flag=1 
    ) 
    if not defined flag >>file3.txt echo %%a 
) 

如果文件很大,你需要的速度,然后设置一个数组文件2的内容将显着加快速度。

这也可以使用更简单的代码,但取决于file1内容。

@echo on 
cd /d "c:\path" 
del file3.txt 2>nul 
for /f "delims=" %%a in (file1.txt) do (
    findstr "^%%a$" file2.txt >nul || >>file3.txt echo %%a 
) 
4

foxidrive显示的FINDSTR方法绝对是解决问题的最快的纯批处理方法,尤其是在file2很大的情况下。但是,有很多情况会导致它失败:文件1中的正则表达式元字符,文件1中的引号和/或反斜杠等。有关所有潜在问题,请参见What are the undocumented features and limitations of the Windows FINDSTR command?。多一点工作可以使解决方案更可靠。

  • 搜索应当明确地字面
  • 搜索应该是
  • 在搜索线的任何反斜线应被转义为\\
  • 每个搜索应存储在一个临时精确匹配(整个线)文件和\G:file选项

此外,您不描述每行的格式。由于<tab><space>的默认delims选项,FOR/F语句将只读取每行的第一个字。我怀疑你想把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 

有一个非常快速的一个在线解决方案,如果你的文件2中不包含\"和你有能力做一个区分大小写的搜索:简单地恢复FINDSTR搜索来查找文件1中不存在任何线在文件2中。由于Why doesn't this FINDSTR example with multiple literal search strings find a match?,搜索必须不区分大小写。

findstr /livxg:"file2.txt" "file1.txt" >"file3.txt" 

如果文件2包含\"因为逃避问题,这是行不通的。您可以对file2进行预处理并转义所有\,但如果您将自己限制为纯批处理解决方案,那么您可以使用第一种解决方案。

如果你愿意使用hybrid JScript/batch utility called REPL.BAT,那么我有一个非常简单和有效的解决方案。 REPL.BAT对标准输入的每一行执行正则表达式搜索和替换操作,并将结果写入标准输出。

假设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 

注意,该解决方案还必须进行区分大小写的比较。