String 如何在日志文件中查找子字符串并使用dos批处理文件增加计数器

String 如何在日志文件中查找子字符串并使用dos批处理文件增加计数器,string,batch-file,token,dhcp,String,Batch File,Token,Dhcp,谁能帮我制作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,

谁能帮我制作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”中递增

同样,对于ID 11,如果IP以172.20.55或172.20.56开始,则应在计数器“RenewPoolA”中递增,如果IP以172.30.55或172.30.56开始,则应在“RenewPoolB”中递增

到目前为止,我所做的如下

@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个池,我必须这样做。在日志文件中,几乎有100000个条目。将此数量的行与每个池匹配将花费太多时间。因此,目标是在增加值后跳出“if条件”,并缩短批处理文件的执行时间


还有一件事,日志文件包含相同mac地址的不同时间的重复条目。我需要增量将只对mac地址的唯一条目运行。

给你。我相信你能解决剩下的问题

@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%

这是否满足您的需要:

@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
@ECHO关闭
SETLOCAL ENABLEDELAYEDEXPANSION
::删除以$or开头的变量#
对于%%b IN($#)DO For/F“delims=”%%a IN('set%%b 2^>Nul')DO set“%%a=”
对于(q21935716.txt)中的/f“令牌=1-4 delims=。”%%a(
如果“%%d”==”(设置$%%a=%%b)其他(设置#%%b.%c.%d=%%a)
)
对于/f“tokens=1,5,6,7delims=,”%(q21935716.log)中的%%a(
如果定义$%a如果定义#%%b.%%c.%%d(集/a!$%a!!#%%b.%%c.%%d!+=1)
)
对于('set$')中的/f“tokens=2delims==”%%a,请设置%%a
后藤: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
。这意味着poolname行将有2个令牌,ip行将有4个令牌。然后设置变量$poolname和#ip,分别包含ID和poolsection

然后是读取日志文件的问题,
空间的发送者,这意味着令牌1,5,6,7是感兴趣的。只有当$ID和#IP都存在时,才是兴趣线。在tose行中,您需要递增poolnamepoolsection


的最后一个
只列出了池名。

当通过复杂测试选择结果时,最简单、最快速的累积结果的方法是不单独识别每个结果,而是累积所有相关结果组,并在最后提取所需结果。在您的情况下,这可以通过以下两种方式轻松实现:

@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
您甚至可以使用第二个数组将这些结果中的“NewPoolA”消息替换为“池A中的新请求”消息<代码>;-)

上次编辑

由于原始问题中未包含新的详细信息,此解决方案已修改多次。为了避免混淆,我删除了以前的解决方案,只发布了最后一个。下面的批处理代码仅累积对唯一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!
   )
)

+1很好,我正要提出同样的建议:-)为什么生活会变得复杂,嗯?这很好:)findstr“^10”是否也与日志文件中的IP匹配,例如“…172.20.55.10,PC2…”。这个“10”是IP地址。匹配ID的检查是否有效?还有一件事,我已经更彻底地检查了日志文件。对于同一mac地址,它包含不同时间的重复条目。我已经更新了上面的示例。我需要增量将运行唯一的mac地址条目。这可能需要再创建一个文件,该文件具有ID 10和11的唯一条目。10之前的
^
意味着10必须从行首开始,并且与ip地址的一部分不匹配,但它不处理重复的mac地址。@foxidrive在执行时,您能帮助处理重复的mac地址吗?它说缺少操作员:(Total NewPoolA request为2 Total NewPoolB request为2 Total RenewPoolA request为0 Total RenewPoolB request为0我认为使用问题中的
new
数据得出的结果是错误的。由于日志文件中存在此类条目,因此出现缺少运算符错误“31,02/21/14,00:00:37,DNS更新失败,172.17.110.13,TAR-CAR-051180L.WTPK.local,-1”,此方法创建一系列变量,在其名称中包含ID、IP和MAC地址,并使用
set/a
命令递增这些变量,因此名称不能包含任何算术运算符,如减号(原始示例数据中没有这些字符)。也许可以修改该方法来处理此问题,但在这种情况下,我需要对这些字段中可能出现的字符进行完整描述…算术运算符是该字段中唯一可能出现的字符。第二种可能是,名称字段包含我在上一篇评论中已经提到的.And-符号.谢谢你的支持