任何人都可以帮我制作Windows批处理文件,以便从日志文件中找到子字符串。 log.log文件的示例如下所示
ID,Date,Time,Description,IP Address,Host Name,MAC Address
10,02/21/14,00:29:45,Assign,172.20.55.50,PC1,123456789AB1,
31,02/21/14,00:29:45,DNS Update,172.20.55.50,PC1,123456789AB1,
10,02/21/14,00:29:45,Assign,172.30.55.50,PC2,123456789AB2,
31,02/21/14,00:29:45,DNS Update,172.30.55.50,PC1,123456789AB2,
10,02/21/14,00:29:45,Assign,172.20.56.60,PC3,123456789AB3,
10,02/21/14,00:29:45,Assign,172.30.55.60,PC4,123456789AB4,
**11,02/21/14,00:30:45,Assign,172.30.55.10,PC2,123456789AB5,**
**11,02/21/14,00:30:46,Assign,172.30.55.10,PC2,123456789AB5,**
**31,02/21/14,00:00:37,DNS Update Failed,172.17.110.13,TAR-CAR-051180L.WTPK.local,-1,**
这基本上是DHCP日志文件。目标是计算新分配IP请求的数量(其ID为10)和更新IP请求的数量(其ID为11)。
对于ID 10,如果IP以172.20.55或172.20.56开头,则应在计数器“NewPoolA”中递增,如果IP以172.30.55或172.30.56开始,则应在“NewPoolB”中递增。 / p>
类似于ID 11,如果IP以172.20.55或172.20.56开头,它应该在计数器“RenewPoolA”中递增,如果IP以172.30.55或172.30.56开始,它应该在“RenewPoolB”中递增。 / p> 到目前为止,我所做的是在
之下@echo off
Setlocal EnableDelayedExpansion
set /a NewPoolA=0
set /a NewPoolB=0
set /a RenewPoolA=0
set /a RenewPoolB=0
for /F "tokens=1-6 delims=," %%a in (log.log) do (
if %%a equ 10 (
rem if %%e contains 172.20.55 (
set /a NewPoolA += 1
goto someLabel
)
rem else if %%e contains 172.20.56 (
set /a NewPoolA += 1
goto someLabel
)
rem else if %%e contains 172.30.55 (
set /a NewPoolB += 1
goto someLabel
)
rem else if %%e contains 172.30.56 (
set /a NewPoolB += 1
goto someLabel
)
rem -------- if id 10 and not match any condition then
goto someLabel
) else if %%a equ 11 (
rem if %%e contains 172.20.55 (
set /a RenewPoolA += 1
goto someLabel
)
rem else if %%e contains 172.20.56 (
set /a RenewPoolA += 1
goto someLabel
)
rem else if %%e contains 172.30.55 (
set /a RenewPoolB += 1
goto someLabel
)
rem else if %%e contains 172.30.56 (
set /a RenewPoolB += 1
goto someLabel
)
rem -------- if id 11 and not match any condition then
goto someLabel
)
)
echo Total new request in Pool A is %NewPoolA%
echo Total renewal request in Pool A is %RenewPoolA%
echo Total new request in Pool B is %NewPoolB%
echo Total renewal request in Pool B is %RenewPoolB%
这是逻辑和我的理解,它将如何运作。我不知道dos批处理命令的语法。
这两个池只是一个例子。我有80个游泳池,我必须这样做。在日志文件中有近100,000个条目。要将这个行数与每个池相匹配将花费太多时间。因此,目标是在递增值后跳出“if条件”并缩短批处理文件的执行时间。
另外一件事,日志文件包含相同mac地址的不同时间的重复条目。我需要增量只运行mac地址的唯一条目。
答案 0 :(得分:1)
这是否符合您的要求:
@echo off
for /f %%a in ('type "file.csv"^|findstr "^10," ^|findstr ",172.20.55 ,172.20.56"^|find /c /v ""') do set AAA-NewPoolA=%%a
for /f %%a in ('type "file.csv"^|findstr "^10," ^|findstr ",172.30.55 ,172.30.56"^|find /c /v ""') do set AAA-NewPoolB=%%a
for /f %%a in ('type "file.csv"^|findstr "^11," ^|findstr ",172.20.55 ,172.20.56"^|find /c /v ""') do set AAA-ReNewPoolA=%%a
for /f %%a in ('type "file.csv"^|findstr "^11," ^|findstr ",172.30.55 ,172.30.56"^|find /c /v ""') do set AAA-ReNewPoolB=%%a
set aaa
pause
答案 1 :(得分:1)
通过复杂测试选择结果时,最简单,最快速的方法是不分别识别每个结果,但累积所有相关结果组并在结束时提取所需结果。在您的情况下,这可以通过二维 array以这种方式轻松实现:
@echo off
setlocal EnableDelayedExpansion
rem Accumulate results for all ID.IP (first 3 groups) combinations
for /F "skip=1 tokens=1,5-7 delims=,." %%a in (log.log) do (
set /A requests[%%a.%%b.%%c.%%d]+=1
)
rem Get desired results
set /A NewPoolA = requests[10.172.20.55] + requests[10.172.20.56]
set /A NewPoolB = requests[10.172.30.55] + requests[10.172.30.56]
set /A RenewPoolA = requests[11.172.20.55] + requests[11.172.20.56]
set /A RenewPoolB = requests[11.172.30.55] + requests[11.172.30.56]
echo Total new request in Pool A is %NewPoolA%
echo Total renewal request in Pool A is %RenewPoolA%
echo Total new request in Pool B is %NewPoolB%
echo Total renewal request in Pool B is %RenewPoolB%
您还可以充分利用数组提供的灵活性,以更简单的方式定义80个池。例如:
@echo off
setlocal EnableDelayedExpansion
rem Accumulate results for all ID.IP (first 3 groups) combinations
for /F "skip=1 tokens=1,5-7 delims=,." %%a in (log.log) do (
set /A requests[%%a.%%b.%%c.%%d]+=1
)
rem Get and show desired results from a long pool definition list
for %%A in ("NewPoolA=10 172.20.55+10 172.20.56"
"NewPoolB=10 172.30.55+10 172.30.56"
"RenewPoolA=11 172.20.55+11 172.20.56"
"RenewPoolB=11 172.30.55+11 172.30.56") do (
for /F "tokens=1-5 delims==+ " %%a in (%%A) do (
set /A %%a=requests[%%b.%%c]+requests[%%d.%%e]
echo Total %%a request is !%%a!
)
)
您的数据的输出示例:
C:\> test
Total NewPoolA request is 2
Total NewPoolB request is 2
Total RenewPoolA request is 0
Total RenewPoolB request is 1
您甚至可以使用第二个数组中的“池A中的新请求”替换这些结果中的“NewPoolA”消息! ;-)
最后编辑
此解决方案已多次修改,原因是新问题未包含在原始问题中。为了避免混淆,我删除了以前的解决方案并发布了最后的解决方案。下面的批处理代码仅累加对唯一MAC地址的请求,忽略等于-1的MAC地址,并允许除IP地址之外的任何字段中的点。
@echo off
setlocal EnableDelayedExpansion
rem Accumulate results for all ID.IP(first 3 groups).MAC_addr combinations
rem NEW: Ignore MAC_addresses equal to -1
for /F "skip=1 tokens=1,5,7 delims=," %%a in (log.log) do (
if "%%c" neq "-1" for /F "tokens=1-3 delims=." %%i in ("%%b") do (
set /A requests[%%a.%%i.%%j.%%k.%%c]+=1
)
)
rem Get and show desired results from a long definition list
rem NEW: Only accumulate requests for unique MAC addresses (count=1)
for %%A in ("NewPoolA=10 172.20.55+10 172.20.56"
"NewPoolB=10 172.30.55+10 172.30.56"
"RenewPoolA=11 172.20.55+11 172.20.56"
"RenewPoolB=11 172.30.55+11 172.30.56") do (
for /F "tokens=1-5 delims==+ " %%a in (%%A) do (
set %%a=0
for /F "tokens=2 delims==" %%x in ('set requests[%%b.%%c 2^>NUL') do (
if %%x equ 1 set /A %%a+=1
)
for /F "tokens=2 delims==" %%x in ('set requests[%%d.%%e 2^>NUL') do (
if %%x equ 1 set /A %%a+=1
)
echo Total %%a request is !%%a!
)
)
答案 2 :(得分:0)
你走了。我相信你可以解决剩下的问题
@echo off
setlocal
set "NewPoolA=0"
set "NewPoolB=0"
set "RenewPoolA=0"
set "RenewPoolB=0"
for /F "tokens=1-6 delims=," %%a in (log.log) do (
if "%%~a" equ "10" (
for /f %%b in ('echo "%%e"^|Findstr /c:"172.20.55" /c:"172.20.56"') do (
set /a NewPoolA+=1
)
)
)
echo Total new request in Pool A is %NewPoolA%
答案 3 :(得分:0)
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:: remove variables starting $ or #
For %%b IN ($ #) DO FOR /F "delims==" %%a In ('set %%b 2^>Nul') DO SET "%%a="
FOR /f "tokens=1-4delims=. " %%a IN (q21935716.txt) DO (
IF "%%d"=="" (SET $%%a=%%b) ELSE (SET #%%b.%%c.%%d=%%a)
)
FOR /f "tokens=1,5,6,7delims=.," %%a IN (q21935716.log) DO (
IF DEFINED $%%a IF DEFINED #%%b.%%c.%%d (SET /a !$%%a!!#%%b.%%c.%%d!+=1)
)
FOR /f "tokens=2delims==" %%a IN ('set $') DO SET %%a
GOTO :EOF
这是一个相当灵活的例程,因为你有80个游泳池。
文件q21935716.txt
包含以下内容:
10 newpool
11 renewpool
A 172.20.55
A 172.20.56
B 172.30.55
B 172.30.56
显然,ID + poolname或poolsection + IP的行。
第一步是清除以$
或#
开头的eny变量。
下一步是使用q21935716.txt
或.
作为分隔符来阅读文件space
。这意味着poolname行将有2个令牌和ip行4.然后设置变量$ poolname和#ip,分别包含ID和poolsection。
然后是读取日志文件,.
,
或space
的分隔符,这意味着令牌1,5,6,7是有意义的。只有$ ID和#IP都存在才是感兴趣的行。在tose行中,您需要增加poolnamepoolsection。
最终for
只列出了池名。