batch-filefor-loopfindstr

Batch file Nesting findstr inside a loop


I'm trying to run the prntmngr.vbs script. I'm trying to find strings like Printer name, server name, etc. There are about 80-200 printers on each server I want it to pipe the information in a csv format.

I'm having trouble nesting the findstr's and loops to get the information. I've pieced together some things.

running the vbs gives me every printer and its information.

The VBS outputs every printer in a block of information as follows. Theres about 80 printers on this one server. I'll worry about scoping out to other servers, as long as I can get it to output the information.

Server name lak-print01
Printer name 1015_Q1
Share name 1015_Q1
Driver name HP LaserJet 4350 PCL 5e
Port name IP_192.168.15.249
Comment Trust & Savings
Location 43rd & Meridian
Print processor HPCPP5r1
Data type RAW
Parameters
Attributes 8776
Priority 1
Default priority 0
Average pages per minute 0
Printer status Other
Extended printer status Offline
Detected error state Offline
Extended detected error state Other

Server name lak-print01
Printer name 1014_Q1
Share name 1014_Q1
Driver name Canon iR3225 PCL5e
Port name IP_192.168.14.245
Comment CSR and Teller Printer
Location Summit
Print processor WinPrint
Data type RAW
Parameters
Attributes 10824
Priority 1
Default priority 0
Average pages per minute 0
Printer status Idle
Extended printer status Unknown
Detected error state Unknown
Extended detected error state Unknown

Server name lak-print01
Printer name 1011_Q3
Share name 1011_Q3
Driver name HP LaserJet 4200 PCL 6
Port name IP_192.168.11.247
Comment HP LaserJet 4200 not being used can delete
Location Spanaway
Print processor HPZPP3xy
Data type RAW
Parameters
Attributes 8778
Priority 1
Default priority 0
Average pages per minute 0
Printer status Idle
Extended printer status Unknown
Detected error state Unknown
Extended detected error state Unknown

for instance I'd love the output to be a csv that outputs the example vbs to

lak-print01,1015_Q1,HP LaserJet 4350 PCL 5e,IP_192.168.15.249,Trust & Savings,43rd & Meridian,Other
lak-print01,1014_Q1,Canon iR3225 PCL5e,IP_192.168.14.245,CSR and Teller Printer,Summit,Idle

pulling find strings for printer server, printer name, printer driver, port name, comment, location, status

Ive gotten a working script

@echo off

SetLocal enabledelayedexpansion

cscript prnmngr.vbs -l -s lak-print01 >test.csv

for /f "tokens=3*" %%i in ('findstr /i /c:"Printer name" /i /c:"Server name" /i /c:"Printer status" /i /c:"Driver name" test.csv') do @echo %%i, 
endlocal

That outputs

1005_Q2,
HP,
Other,
status,
lak-print01,
1004_Q2,
HP,
Idle,
status,
lak-print01,
1004_Q1,
HP,
Idle,
status,
lak-print01,
1003_Q2,
HP,
Idle,
status,
lak-print01,
1003_Q1,
HP,
Idle,
status,

Which is great, however its only pulling the first word of the driver name even with the wildcard in the tokens. Now I just have to figure out how to make it carriage return after a for loop is complete to start a new line with new set of data.


Solution

  • @ECHO Off
    SETLOCAL enabledelayedexpansion
    :: remove variables starting $
    FOR  /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
    (FOR /f "delims=" %%a IN (q25900051.txt) DO CALL :analyse "%%a")>printers.csv
    
    GOTO :EOF
    
    :analyse
    SET "line=%~1"
    SET /a fieldnum=0
    FOR %%s IN ("Server name" "Printer name" "Driver name"
                "Port name" "Comment" "Location" "Printer status" 
            "Extended detected error state") DO CALL :setfield %%~s
    GOTO :eof
    
    :setfield
    SET /a fieldnum+=1
    SET "linem=!line:*%* =!"
    SET "linet=%* %linem%"
    IF "%linet%" neq "%line%" GOTO :EOF 
    IF "%linem%"=="%line%" GOTO :EOF
    SET "$%fieldnum%=%linem%"
    IF NOT DEFINED $8 GOTO :EOF 
    SET "line="
    FOR /l %%q IN (1,1,7) DO SET "line=!line!,!$%%q!"
    ECHO !line:~1!
    :: remove variables starting $
    FOR  /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
    GOTO :eof
    

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

    This could be automated a little further, but I don't have the time at present.

    Essentially, it analyses each line and sets a field number 1..number-of-columns+1. When the number-of-columns+1'th column is filled, the output is accumulated and echoed and the $ variables reset.

    The "Manual" part is entering the names of the fields to be selected, including the "end of block" field as the last entry; then the variable $8 and the top limit for %%q are set - 8 fields potentially being analysed, 7 being output.

    The jiggery-pokery with line, linem (modified line - minus the field name) and linet (total line - reconstructed) is first to extract the required data by removing the string as far as the target. The line is then reconstructed as linet and compared to the original version in line. This allos us to distinguish between the line that starts Printer status and theline that starts Extended printer status - when the target is printer status, the first line will be reconstructed to match the original, but the second will lop off Extended printer status then re-add printer status, so the reconstructed line does not match the original...


    Modified for new requirement - output to file.

    It's in a rather odd place - parenthisise the for statement invoking thesubroutines - any output from echo statements within the subroutines will be redirected to the file nominated.