Search code examples
windowsbatch-filescriptingfindstr

Using Findstr with specific range or other method


I only want to find specific lines in his text file, so i figure that using range would be a good idea. But i can seem to find any tutorial online. please help..

An example of the text file

XXX scan report for 192.0.0.0
exampleexampleexampleexampleexample
OS: windows 8
exampleexampleexampleexample
exampleexampleexampleexample
PORT     STATE  SERVICE          VERSION
21/tcp   close  ftp
80/tcp   open   http             Microsoft ISS
exampleexampleexampleexample
exampleexampleexampleexample

XXX scan report for 192.0.0.1
exampleexampleexampleexampleexample
exampleexampleexampleexample
exampleexampleexampleexample
PORT     STATE  SERVICE          VERSION
21/tcp   close  ftp
80/tcp   open   http             Microsoft ISS
exampleexampleexampleexample
exampleexampleexampleexample

I wanted to get IP address, OS Details and Port status into a spreadsheet.

My code:

@echo off
set file=C:\Users\1.txt
set match=report for
set match1=OS


findstr /c:"%match%" %file%
findstr /c:"%match1%" %file%
findstr /c:"tcp " /c:"udp " %file%

for /f "tokens=1-5" %%a in ('findstr /c:"%match%" %file%') do (
echo "IP Address:","%%e" >> report1.csv

for /f "tokens=1,2 delims=:*" %%a in ('findstr /c:"%match1%" %file%') do 
( 
echo "Operating System: ","%%b" >> report1.csv
echo "PORT","STATE","SERVICE","VERSION" >> report1.csv  

for /f "tokens=1-4 delims=: " %%a in ('findstr /c:"tcp " /c:"udp " 
%file%') do (
echo "%%a","%%b","%%c","%%d" >> report1.csv
)

)

)

There is a big problem with this code and it is in the for loop. The code will get the first ip then will proceed to get the os details, but not ever ip have the os details, so the os details will be placed in the wrong ip.

Another problem with the code is that it will list all os and port details under one ip address. And the next ip address will also be the same, it will have all the os and port details as well.

Please do help me to solve this problem. Or is there any other method like call?


Solution

  • @ECHO OFF
    SETLOCAL
    SET "sourcedir=U:\sourcedir"
    SET "destdir=U:\destdir"
    SET "filename1=%sourcedir%\q43335765.txt"
    SET "outfile=%destdir%\outfile.txt"
    >"%outfile%" ECHO IP,OS,PORT,STATUS,SERVICE,VERSION
    FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
     CALL :process %%a
    )
    
    GOTO :EOF
    
    :process
    ECHO %*|FIND "scan report for " >NUL
    IF NOT ERRORLEVEL 1 GOTO newip
    IF "%~1"=="OS:" SET "$os=%*"&GOTO :eof
    ECHO %~1|FIND "/">NUL
    IF ERRORLEVEL 1 GOTO :EOF 
    FOR /f "tokens=1,2,3*" %%p IN (
     "%*") DO >>"%outfile%" ECHO %$ip%,%$os:*: =%,%%p,%%q,%%r,%%s
    GOTO :eof
    
    :newip
    IF "%~2" neq "" shift&GOTO newip
    SET "$ip=%~1"
    SET "$os=:  "
    
    GOTO :eof
    

    You would need to change the settings of sourcedir and destdir to suit your circumstances.

    I used a file named q43335765.txt containing your data for my testing.

    Produces the file defined as %outfile%

    Having established the filenames, put the header line in the output file and process each line of the file through :process

    In :process, detect the key string indicating a ne data item. If found, go to :newip which simply shuffles the data line along until only the last entry remains and assign this last entry to $ip. Set $ip to :Space + any special string you want to represent "not found" (like unknown for instance)

    If the line doesn't contain the keystring, see whether the first token is OS:, and set $os to the entire original line if it is.

    Otherwise, lookk for a / in the first token. If it's not there, abandon processing this line, otherwise simply tokenise the line, selecting the first to thid and rest and output using the saved ip, the saved os, except for the part before the first :Space and the four data line entries, all separated by commas.


    Revision to cater for | in data - replace with /

    @ECHO OFF
    SETLOCAL
    SET "sourcedir=U:\sourcedir"
    SET "destdir=U:\destdir"
    SET "filename1=%sourcedir%\q43335765.txt"
    SET "outfile=%destdir%\outfile.txt"
    >"%outfile%" ECHO IP,OS,PORT,STATUS,SERVICE,VERSION
    FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
     SET "line=%%a"
     CALL :preprocess
    )
    
    GOTO :EOF
    
    :preprocess
    SET "line=%Line:|=/%"
    CALL :process %line%
    GOTO :eof
    
    :process
    ECHO %*|FIND "scan report for " >NUL
    IF NOT ERRORLEVEL 1 GOTO newip
    IF "%~1"=="OS:" SET "$os=%*"&GOTO :eof
    ECHO %~1|FIND "/">NUL
    IF ERRORLEVEL 1 GOTO :EOF 
    FOR /f "tokens=1,2,3*" %%p IN (
     "%*") DO >>"%outfile%" ECHO %$ip%,%$os:*: =%,%%p,%%q,%%r,%%s
    GOTO :eof
    
    :newip
    IF "%~2" neq "" shift&GOTO newip
    SET "$ip=%~1"
    SET "$os=:  "
    
    GOTO :eof
    

    Shows the need to provide a representative data sample...

    With characters that have special meaning like |, assign to a variable and call a preprocessor to convert all | to / (or whatever else is desired) and then call the process with the result.

    Formula: set "var=%somevar:string1=string2%"

    will assign to var the value of somevar with all occurrences of string1 replaced by string2. The enclosing quotes in a set command ensure that any stray trailing spaces on the line are not included in the value assigned.