findstr:搜索字符串太长

时间:2016-01-29 17:24:25

标签: windows shell batch-file scripting findstr

我正在尝试比较IP列表并通过在Windows中使用findstr命令输出差异,并且很难让它工作。我正在使用的命令是:

编辑:我的目标是将已成功扫描的IP与已成功扫描的IP进行比较,并输出不在 IPsSuccessfullyScannedwithAuthentication.txt 但在中的文件IPsSuccessfullyScanned.txt IPsSuccessfullyScannedButNotAuthenticated.txt

假设 IPsSuccessfullyScanned.txt 包含

  

192.168.0.1

     

192.168.0.2

     

192.168.0.3

     

192.168.0.4

     

192.168.0.5

     

192.168.0.6

     

192.168.0.7

     

192.168.0.8-192.168.0.12

IPsSuccessfullyScannedwithAuthentication.txt (这是经过身份验证并成功扫描的IP)包含

  

192.168.0.1

     

192.168.0.2

     

192.168.0.3

     

192.168.0.4

     

192.168.0.6

     

192.168.0.8-192.168.0.10

     

192.168.0.12

我的 IPsSuccessfullyScannedButNotAuthenticated.txt 应该有:

  

192.168.0.5

     

192.168.0.7

     

192.168.0.11

findstr /vixg:IPsSuccessfullyScanned.txt IPsSuccessfullyScannedwithAuthentication.txt> IPsSuccessfullyScannedButNotAuthenticated.txt

我想要实现的目标非常类似于这篇文章:

.bat file to compare two text files and output the difference

这是我的问题,但IPs2.txt中的文件大小为720字节。 当我研究findstr命令时,我发现在进行正则表达式搜索时,最大搜索字符串长度为254个字节。长度在255字节和511字节之间的正则表达式将导致FINDSTR:ERRORLEVEL 2出现内存不足错误。

正则表达式长度> 511字节会导致 FINDSTR:搜索字符串太长。错误。 (这是我目前得到的错误)

我的问题是:我可以使用哪些替代方案来比较两个文本文件?如果有任何其他建议可以尽可能简单地解决我的问题,即使是bat文件也可以提供帮助。

参考文献:

http://ss64.com/nt/findstr-escapes.html

What are the undocumented features and limitations of the Windows FINDSTR command?

2 个答案:

答案 0 :(得分:0)

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q35090416.txt"
SET "filename2=%sourcedir%\q35090416_2.txt"
:: remove variables starting $
FOR  /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
:: Read first file into memory
FOR /f "tokens=1*delims=]" %%a IN ('find /n /v "" "%filename1%"') DO SET "$%%a=%%b"
FOR /f "usebackqdelims=" %%a IN ("%filename2%") DO (
 SET "same="
 FOR /f "tokens=1*delims==" %%b IN ('SET $ 2^>nul') DO (
  IF /i "%%a"=="%%c" SET "same=y"
 )
 IF NOT DEFINED same ECHO(%%a
)

GOTO :EOF

您需要更改sourcedirfilename*的设置以适合您的具体情况。

我使用了名为q35090416*.txt的文件,其中包含一些虚拟数据供我测试。

此例程生成的报告是第二个文件中包含的行,这些行未包含在第一个文件中,它似乎是findstr /vixg命令的对象。请清楚解释一下你要做什么 - 如果我们不确切知道对象是什么,我们就无法解决一些无法解决的问题。

如果任何字符串启动]或者遇到批处理字符串处理遇到的任何常见问题,例程可能会出现问题。

您的修改从根本上改变了问题。该问题与文件的内容有很大关系。 findstr限制为254个字符是每行的限制,而不是整个文件的限制。

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q35090416.txt"
SET "filename2=%sourcedir%\q35090416_2.txt"
:: remove variables starting $
FOR  /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
:: Read first file into memory
FOR /f "usebackqtokens=1*delims=-" %%a IN ("%filename2%") DO (
 IF "%%b"=="" (SET "$%%a=Y") ELSE (
  FOR /f "tokens=1-4,8delims=." %%p IN ("%%a.%%b") DO FOR /l %%x IN (%%s,1,%%t) DO SET "$%%p.%%q.%%r.%%x=y"
 )
)
FOR /f "usebackqtokens=1*delims=-" %%a IN ("%filename1%") DO (
 IF "%%b"=="" (IF NOT DEFINED $%%a ECHO %%a) ELSE (
  FOR /f "tokens=1-4,8delims=." %%p IN ("%%a.%%b") DO FOR /l %%x IN (%%s,1,%%t) DO (
  IF NOT DEFINED $%%p.%%q.%%r.%%x ECHO %%p.%%q.%%r.%%x
  )
 )
)

GOTO :EOF

这个解决方案应该适合。我使用与SO问题编号对应的文件名进行测试,以便在需要时可以重新查看问题。因此,filename1是您成功扫描的列表,filename2是经过身份验证的列表,输出是差异。

您可以将整个第二个for语句括在括号中,以便根据需要将输出重定向到文件,即

...
for ....
)
...

变为

...
(
for ....
)
)>somefilename
...

将输出重定向到somefilename

该例程首先删除以$开头的所有环境变量(通常没有,但确保这样做)

然后检查第二个文件,将行拆分为%%a%%b(分隔符“ - ”两侧的两个标记) 如果第二个令牌不存在,则它设置一个环境变量,例如“$ 192.168.0.1”。如果确实存在,则重新标记“%% a。%% b”(注意.)并分配1-4和8标记,因此“192.168.0.8-192.168.0.10”变为“192.168”。 0.8“和”192.168.0.10“;这是“ 192 168 0 8 .192.168.0。 10 “并将令牌192,168,0,8 and 10分配给%%p..%%t。然后,for /l循环会将值分配给$192.168.0.8$192.168.0.10

接下来是一个类似的故事,但这次例程只是检查是否设置了变量。如果未设置,则编号为echo

答案 1 :(得分:0)

@echo off
setlocal EnableDelayedExpansion

set "d="
< input1.txt (
   for /F "tokens=1-4,8 delims=.-" %%a in (input2.txt) do (
      if "%%e" equ "" (set "n=%%d") else set "n=%%e"
      for /L %%i in (%%d,1,!n!) do call :check %%a.%%b.%%c.%%i
   )
) > result.txt
goto :EOF


:check
   if not defined d (
      set "line="
      set /P "line="
      if not defined line exit /B
      for /F "tokens=1-4,8 delims=.-" %%A in ("!line!") do (
         set "abc=%%A.%%B.%%C"
         set "i=%%D"
         set "d=%%E"
      )
   ) else (
      set /A i+=1
      if !i! equ !d! set "d="
   )
   if "%abc%.%i%" equ "%1" exit /B
   echo %abc%.%i%
goto check

input1.txt文件较大(192.168.0.5192.168.0.7 IP&#39; s),input2.txt较短的文件,没有此类IP&#39; s 。输出示例:

192.168.0.5
192.168.0.7
192.168.0.11