如何从NSLOOKUP过滤掉IP6和已知的IP4地址?

时间:2013-11-25 07:42:43

标签: batch-file for-loop find compare findstr

我遇到的问题是,某些DNS条目提供了别名和附加IP6地址,而其他DNS条目确实提供了多个IP4地址,这些地址可能会因应答而变化。

仅询问DNS服务器的IP4,会导致脚本超时,并且无法解决更改(负载均衡)的IP4地址。

对于测试,您可以使用这些域名,例如:

  • www.stackoverflow.com
  • www.heise.de
  • www.dell.de

这些都是很好的例子,因为第一个域确实在IP地址之后提供了一个别名,我可以通过它轻松查找。但第二个确实提供了一个IP6,它也应该被过滤掉,并且最后不仅仅是戴尔提供了不同的地址,几乎每个回复的答案。

这是我的代码的部分内容:

set TESTDNS=www.dell.de
set TESTIP=143.166.83.190

FOR /F "skip=1 delims=: tokens=2 usebackq" %%j in (`nslookup %TESTDNS% 2^>NUL 1^| find "Address"`) do set XIP=%%j 
set XIP=%XIP: =%

do more like compare etc. ....
if NOT %TESTIP%==%XIP% ( ... )

有人可以告诉我如何过滤掉IP6地址(可能是使用findstr [0-9] - 但是如何检查我最后一次知道的IP地址是否在提供的新答案中,因为如果是这样我不需要在我的配置中改变它。

SOLUTION:

从MC ND的回答中,我使用他的函数作为直接代码(用于另一个循环),而不使用调用。我真正改变了var名称的唯一内容是从IP中添加条带空格,否则会破坏函数"1.2.3.4" =! "1.2.3.4 " D)

for x do ( ...

      REM go get dns resolution and set vars to test and compare
      set "XIP="
        for /f "skip=1 tokens=*" %%a in ('nslookup "%TESTDNS%" 2^>nul ^| findstr /i /r /c:"address[e]*[s]*:.*\." /c:"address[ ]*=.*\." /c:"^[   ][  ]*[0-9].*\." ') do (
            rem get nslookup output
            set "_line=%%a"
            rem remove spaces
            set "_line=!_line: =!"
            rem parse line
            for /f "tokens=1,* delims=:=" %%b in ("!_line!") do (
                rem retrieve the correct section of the line
                if "%%c"=="" (
                    set "XTIPX=%%b"
                ) else (
                    set "XTIPX=%%c"
                )
                REM trim whitespaces from var
                set XTIPX=!XTIPX: =!
                rem test address match to old address
                if "!XTIPX!"=="%TESTIP%" (
                    set "XIP=!XTIPX!"
                    goto endRESTESTDNS
                )
                rem if no match, the first address found is saved
                if not defined XIP set "XIP=!XTIPX!"
            )
        )
        :endRESTESTDNS

do more like compare etc. ....

实验代码:

                      @ECHO OFF
          SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

          REM ++++++++++++++++++++++++++++ BLAT EMAIL CONFIG ++++++++++++++++++++++++++++++++++++
          set eMailTO=someone@somedomain.somewhere
          set eMailFROM=dnstestscript
          set server=0.0.0.0
          REM you have to install blat of course, here "echo blat ..." is used where it would be
          REM useful to send an email on interesting items, but it is also sent to shell and log
          REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

          REM ++++++++++++++++++++++++++++ SCRIPT CONFIG ++++++++++++++++++++++++++++++++++++++++
          set "XScriptnamE=%~n0"
          set "XSCRIPTDIR=%~dp0"
          set "LOGDIR=%XSCRIPTDIR%\%XScriptnamE%"
          if not exist "%LOGDIR%" mkdir "%LOGDIR%"
          set "LOG=%LOGDIR%\%XScriptnamE%.log"
          REM make errorlooging expand
          set "XLOGX=xpipex && type xpipex && type xpipex >> %LOG%"
          REM or make individual run logs
          REM set "LOG=%LOGDIR%\%XScriptnamE%-%STAMP%.log"
          REM not global vars come here
          set "DNSTESTFILE=%XSCRIPTDIR%\dnstests.txt"
          REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          REM do never set something here at errorlog plz otherwise compare of happened errors wont work
          set errorlog=
          pushd=%XSCRIPTDIR%
          REM ++++++++++++++++++++++++++++ MAKE DATE ++++++++++++++++++++++++++++++++++++++++++++
          for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
          REM make timestamp (date reverse)
          set STAMP=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2%--%ldt:~8,2%-%ldt:~10,2%--%ldt:~12,2%-%ldt:~15,3%
          REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          echo ================================================== >> %LOG%
          echo   Script run at %STAMP% >> %LOG%
          REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

          REM ++++++++++++++++++++++++++++ START ++++++++++++++++++++++++++++++++++++++++++++++++
          REM if the script is run in cmd we see enoght information to follow actions but they are written to a log file too for sheduled use

          REM ++++++++++++ make a loop for each line in file ++++++++++++++++++++++++++++++++++++


          REM read them in different vars to call processing
          REM check for test file
          if NOT exist "%DNSTESTFILE%" (
            set errorlog=%errorlog% : error dns file not exist :
            echo blat error dnsfile
            echo error dnsfile not exist >> %log%
            )
          REM read test file
          set Counter=1
          for /f %%s in (%DNSTESTFILE%) do (
            set "Line_!Counter!=%%s"
            set /a Counter+=1
            )
          set /a NumLines=Counter - 1
          REM make a backup of old test file before nulling it, by files date you see last ip change
          copy /y %DNSTESTFILE% %DNSTESTFILE%.bak 2>&1 > %XLOGX% 
          REM as i found no way to rewrite the specific line i choose to read out all lines in vars, now we nul the file and rewrite lines later
          type NUL > %DNSTESTFILE%
          REM now use vars to call processing
          for /l %%r in (1,1,%NumLines%) do (
            set "q=!Line_%%r!"
            echo. >> %log%
            echo.
            call :check !q!
            )
          REM did all go well or what did we miss?
          if NOT "%errorlog%."=="." (
          echo.
          echo blat summary %errorlog%!
          echo. >> %LOG%
          echo %errorlog%! >> %LOG%
          )
          REM ++++++++++++++++++++++++++++ END +++++++++++++++++++++++++++++++++++++++++++++++++++
          REM next line tells us script did run through code while one may want to save this lines
          echo ==================script finished================= >> %log%
          del xpipex
          break
          goto :eof
          REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

          REM +++++++++++++++++++++++++++++ PROCESSING +++++++++++++++++++++++++++++++++++++++++++
          :check
              REM trim whitespace from beginning and end of line
              for /f "tokens=* delims=" %%z in ("!q!") do ( 
              set "line=!q!"
                REM test if line is valid dns AND ip address syntax BUT only informational because of limited regular expression support of findstr and "1234.2.3.4" is also accepted as well formatted address
                echo !line! | findstr /i /r "^[a-z0-9-]*\.[a-z0-9-]*\.[a-z0-9-]*=[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" >NUL || (
                echo blat error in dns test line syntax with: !line!
                set errorlog=%errorlog% : error in dns test line syntax with: !line! :
                )
              REM test that trimmed line matches at least once "^char=number$" and set vars for test
              echo !line! | findstr /i "^[a-z]*=[0-9]*$" >NUL && do (
              for /f "tokens=1,2 delims==" %%x in ("!q!") do set TESTDNS=%%~x&set TESTIP=%%~y 
              )
              REM trim whitespace from beginning and end of var
              set TESTDNS=%TESTDNS: =%
              set TESTIP=%TESTIP: =%
              echo testing %TESTDNS% to %TESTIP%
              echo checking %TESTDNS%: >> %LOG%
              REM go get dns resolution and set vars to test and compare
    echo. ############################
    nslookup %TESTDNS%
    echo. ############################
              set "XIP="
                for /f "skip=1 tokens=*" %%a in ('nslookup "%TESTDNS%" 2^>nul ^| findstr /i /r /c:"address[e]*[s]*:.*\." /c:"address[ ]*=.*\." /c:"^[   ][  ]*[0-9].*\." ') do (
                    rem get nslookup output
    echo testing %TESTDNS% to %TESTIP% -1
                    set "_line=%%a"
                    rem remove spaces
                    set "_line=!_line: =!"
                    rem parse line
                    for /f "tokens=1,* delims=:=" %%b in ("!_line!") do (
                        rem retrieve the correct section of the line
    echo testing %TESTDNS% to %TESTIP% -2
                        if "%%c"=="" (
                            set "XTIPX=%%b"
                        ) else (
                            set "XTIPX=%%c"
                        )

    echo testing %TESTDNS% to %TESTIP% -3 "!XTIPX!"
    echo !XTIPX! > 1.txt
    echo %TESTIP% > 2.txt

              REM trim whitespace from beginning and end of var
              rem  set XTIPX=!XTIPX: =!

                        rem test address match to old address
                        if "!XTIPX!"=="%TESTIP%" (
    echo testing %TESTDNS% to %TESTIP% -4 !XTIPX!
                            set "XIP=!XTIPX!"
                            goto endRESTESTDNS
                        )
                        rem if no match, the first address found is saved
                        if not defined XIP set "XIP=!XTIPX!"
    echo testing %TESTDNS% to %TESTIP% -5
                    )
                )
                :endRESTESTDNS
                REM if dsn did change
                if NOT %XIP%==%TESTIP% (
                  echo %TESTDNS% now is %XIP%
                  REM inform us
                  echo blat dns for given %TESTDNS% did change from %TESTIP% TO %XIP%!
                  echo dns did change from %TESTIP% TO %XIP%! >> %LOG%
                  REM fill a log-var to report allover later in mail for example
                  set errorlog=%errorlog% : dns for given %TESTDNS% dis change from %TESTIP% TO %XIP%! :
                  REM do not forget to write back
                  echo %TESTDNS%=%XIP% >> %DNSTESTFILE%
                  )
                if %XIP%==%TESTIP% (
                  REM if dns did not change
                  echo ip did not change 
                  REM we should not forget to write back the route to our testfile
                  echo %TESTDNS%=%XIP% >> %DNSTESTFILE%
                  echo - OK >> %LOG%
                  )
    )

          :EOF

1 个答案:

答案 0 :(得分:0)

@echo off

    call :TESTIP "www.dell.de" "1.1.1.1" IP

    echo %IP%

    exit /B


:TESTIP name oldip retrievedIpVar

    setlocal enableextensions enabledelayedexpansion

    set "_name=%~1"
    set "_oldIP=%~2"
    set "_return="
    rem Need a variable with a tab in it to use in findstr
    call :getTab tab

    rem Loop over nslookup filtering output
    rem Get lines in the form 
    rem     Address / Addresses : followed by IP
    rem     blank line start and ip
    rem     www.somewhere.com internet address = ip     

    for /f "skip=1 tokens=*" %%a in ('nslookup "%_name%" 2^>nul ^| findstr /i /r /c:"address[e]*[s]*:.*\." /c:"address[ ]*=.*\." /c:"^[ %tab%][ %tab%]*[0-9].*\." ') do (
        rem get nslookup output
        set "_line=%%a"
        rem remove spaces
        set "_line=!_line: =!"
        rem remove tabs
        set "_line=!_line:%tab%=!"

        rem parse line
        for /f "tokens=1,* delims=:=" %%b in ("!_line!") do (
            rem retrieve the correct section of the line
            if "%%c"=="" (
                set "XIP=%%b"
            ) else (
                set "XIP=%%c"
            )
            rem test address match to old address
            if "!XIP!"=="%_oldIP%" (
                set "_return=!XIP!"
                goto endTESTIP
            )
            rem if no match, the first address found is saved
            if not defined _return set "_return=!XIP!"
        )
    )

:endTESTIP
    endlocal & set "%~3=%_return%"
    goto :EOF

:getTab var
    for /f tokens^=^*^ delims^= %%x in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09"') do ( set "%~1=%%x" )
    goto :EOF

跳过第一行(dns服务器信息)。使用冒号和等号作为分隔符。取第二个令牌以及后面的所有令牌,因为地址可以包含99.99.99.99:999格式的端口。如果不需要端口,请将令牌更改为token=2set "XIP=%%a"

排除IPv6的最简单方法是过滤并获取只有一个点的地址字符串。

已编辑 - 已更改为适应平衡地址,其中包含地址前输出中的=

已编辑2 - 案件数量超出我的想象。更改了代码以处理更多案例并获得更多IP

EDITED 3 - 适合整合到OP解决方案

EDITED 4 - 在nslookup输出中处理初始标签

已编辑5 - 更正选项卡解析的问题