【问题标题】:findstr: search strings too longfindstr:搜索字符串太长
【发布时间】:2016-01-29 17:24:24
【问题描述】:

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

编辑:我的目标是将成功扫描的 IP 与成功扫描并实现身份验证的 IP 进行比较,并将其输出为不在 IPsSuccessfullyScannedwithAuthentication.txt 中但在 中的文件IPsSuccessfullyScanned.txtIPsSuccessfullyScannedButNotAuthenticated.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: Out of memory 错误,ERRORLEVEL 2。

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

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

参考资料:

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

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

【问题讨论】:

  • 对不起,您的问题不清楚。你想要什么结果? IPs1.txt 中不存在的 IPs2.txt 中的行?反之亦然?两个都?另一个?

标签: windows shell batch-file scripting findstr


【解决方案1】:
@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

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

【讨论】:

  • 我编辑了我的帖子,如果您认为您的 bat 文件仍然可以满足我的需要,请告诉我。当我使用上面编写的示例数据运行 bat 文件时,它没有给出预期的结果。我想是因为他们正在比较文字字符串。当谈到 IP 时,他们有时会在 IP 之间加上“-”以缩短我正在使用的程序的长度。有没有办法让批处理文件知道缺少哪个数字?
【解决方案2】:
@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),input2.txt 较短,没有这样的IP。输出示例:

192.168.0.5
192.168.0.7
192.168.0.11

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多