findstr:搜索字符串太长
findstr: search strings too long
我正在尝试比较 IP 列表并使用 Windows 中的 findstr 命令输出差异,但我很难让它工作。我使用的命令是:
编辑:我的 objective 是将成功扫描的 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
我想要实现的与此非常相似post:
.bat file to compare two text files and output the difference
这是我的问题,IPs2.txt 中的文件大小是 720 字节。
当我研究 findstr 命令时,我发现在进行正则表达式搜索时,最大搜索字符串长度为 254 字节。长度在 255 字节到 511 字节之间的正则表达式将导致 FINDSTR:内存不足错误,错误级别为 2。
正则表达式长度 >511 字节导致 FINDSTR:搜索字符串太长。 error. (这是我目前遇到的错误).
我的问题是:我可以使用哪些替代方法来比较这两个文本文件?如果有任何其他建议可以尽可能轻松地解决我的问题,如果可能的话,即使是 bat 文件也能提供帮助。
参考文献:
http://ss64.com/nt/findstr-escapes.html
What are the undocumented features and limitations of the Windows FINDSTR command?
@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
您需要更改 sourcedir
和 filename*
的设置以适合您的情况。
我使用了名为 q35090416*.txt
的文件,其中包含一些用于测试的虚拟数据。
此例程生成的报告是包含在第二个文件中但不包含在第一个文件中的行,这似乎是您的 findstr /vixg
命令的对象。请清楚地解释您想要做什么 - 如果我们不确切知道对象是什么,我们将无法修复不起作用的东西。
如果任何字符串开始 ]
或批处理字符串处理遇到的任何常见问题,例程可能会出现问题。
您的编辑从根本上改变了问题。该问题与文件的 content 有很大关系。 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是认证后的列表,输出就是差值。
如果您愿意,您可以将 entire 第二个 for
语句括在括号中以将输出重定向到文件,即
...
for ....
)
...
变成
...
(
for ....
)
)>somefilename
...
将输出重定向到 somefilename
该例程首先删除所有以 $
开头的环境变量(通常有 none,但这是确定的)
然后它检查第二个文件,将行分成 %%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
循环将一个值赋给 2.168.0.8
到 2.168.0.10
接下来是一个类似的故事,但这次例程只是检查是否设置了变量。如果未设置,则编号为 echo
ed。
@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.5
和 192.168.0.7
IP),input2.txt
文件较短,没有这样的 IP。输出示例:
192.168.0.5
192.168.0.7
192.168.0.11
我正在尝试比较 IP 列表并使用 Windows 中的 findstr 命令输出差异,但我很难让它工作。我使用的命令是:
编辑:我的 objective 是将成功扫描的 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
我想要实现的与此非常相似post:
.bat file to compare two text files and output the difference
这是我的问题,IPs2.txt 中的文件大小是 720 字节。 当我研究 findstr 命令时,我发现在进行正则表达式搜索时,最大搜索字符串长度为 254 字节。长度在 255 字节到 511 字节之间的正则表达式将导致 FINDSTR:内存不足错误,错误级别为 2。
正则表达式长度 >511 字节导致 FINDSTR:搜索字符串太长。 error. (这是我目前遇到的错误).
我的问题是:我可以使用哪些替代方法来比较这两个文本文件?如果有任何其他建议可以尽可能轻松地解决我的问题,如果可能的话,即使是 bat 文件也能提供帮助。
参考文献:
http://ss64.com/nt/findstr-escapes.html
What are the undocumented features and limitations of the Windows FINDSTR command?
@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
您需要更改 sourcedir
和 filename*
的设置以适合您的情况。
我使用了名为 q35090416*.txt
的文件,其中包含一些用于测试的虚拟数据。
此例程生成的报告是包含在第二个文件中但不包含在第一个文件中的行,这似乎是您的 findstr /vixg
命令的对象。请清楚地解释您想要做什么 - 如果我们不确切知道对象是什么,我们将无法修复不起作用的东西。
如果任何字符串开始 ]
或批处理字符串处理遇到的任何常见问题,例程可能会出现问题。
您的编辑从根本上改变了问题。该问题与文件的 content 有很大关系。 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是认证后的列表,输出就是差值。
如果您愿意,您可以将 entire 第二个 for
语句括在括号中以将输出重定向到文件,即
...
for ....
)
...
变成
...
(
for ....
)
)>somefilename
...
将输出重定向到 somefilename
该例程首先删除所有以 $
开头的环境变量(通常有 none,但这是确定的)
然后它检查第二个文件,将行分成 %%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
循环将一个值赋给 2.168.0.8
到 2.168.0.10
接下来是一个类似的故事,但这次例程只是检查是否设置了变量。如果未设置,则编号为 echo
ed。
@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.5
和 192.168.0.7
IP),input2.txt
文件较短,没有这样的 IP。输出示例:
192.168.0.5
192.168.0.7
192.168.0.11