Nick W.
Nick W.

Reputation: 1614

Batch Script Substring from string

Ok, I have been playing around with this for a while and am getting no where. I need to pull the KB number out from a line.

The issue i am having is that some of the KB numbers are 6 characters and some are 7, and can't seem to find a way that will work to error detect the two.

The Two types of errors this makes is as follows

The First one should only have been displayed 6 characts so it added the extra "-" at the end.

x64 KB890830-   2012\MS12-000\WinSec-KB890830-006-P58310-Windows-KB890830-x64-V4.9.exe 

While the second error shows the random "_" because it uses the first KB shown not the second.

ia64    KB_942288   2012\MS12-000\WinSec-KB_942288-007-P58312-WindowsServer2003-KB942288-v4-ia64.exe

EDIT Batch File So Far

@ECHO OFF
SETLOCAL enableDelayedExpansion

IF EXIST Export.csv DEL Export.csv
FOR /F "tokens=*" %%I in ('dir /s /b *.*') DO CALl:Generate "%%I"
pause

:Generate
SETLOCAL
IF "%~x1" NEQ ".exe" (
    If "%~x3" NEQ ".msu" (
        GOTO:EOF
    )
)
CALL:FindArchitecture %1
CALL:FindKB %1
CALL:PathFix %1
ECHO %Architecture%,%KB%,%FilePath%>>Export.csv
CALL:Cleanup
ENDLOCAL
GOTO:EOF


:FindArchitecture
ECHO %1 | FINDSTR "x64"
IF "%ERRORLEVEL%"=="0"  (
    SET Architecture=x64
    SET Count+=1
)
ECHO %1 | FINDSTR "x86"
IF "%ERRORLEVEL%"=="0" (
    SET Architecture=x86
    SET Count+=1
)

ECHO %1 | FINDSTR "ia64"
IF "%ERRORLEVEL%"=="0" (
    SET Architecture=ia64
    SET Count+=1
)

IF "%Count%" GTR "1" (
    SET Architecture=Error
)
SET Count=0
GOTO:EOF

:FindKB
set KBNum="%~1"
set "KBNum=!KBNum:*-KB=!"
ECHO !KBNum!|findstr /I /E /R /c:"-KB[0-9][0-9][0-9][0-9][0-9][0-9][0-9]" >nul 
SET "KB=KB!KBNum:~0,7!"
IF "%KB%" NEQ "" GOTO:EOF
ECHO !KBNum!|findstr /I /E /r /c:"-KB[0-9][0-9][0-9][0-9][0-9][0-9]" >nul
SET "KB=KB!KBNum:~0,6!"
GOTO:EOF

:PathFix
set Path_to_convert=%~1
set Reference_path=%~dp0
set FilePath=!Path_to_convert:*%Reference_path%=!
GOTO:EOF

:Cleanup
SET KBNum=
SET KB=
SET Count=
SET Architecture=
set InstallerPath=
set PathRemoval=
set Path=
GOTO:EOF

Upvotes: 1

Views: 6696

Answers (1)

dbenham
dbenham

Reputation: 130819

OK - siginificant edit after seeing comments from Ken White and the OP.

I'm not sure if you need this, but FINDSTR with a regular expression can validate that the line has the pattern: "-KB" followed by 7 digits, followed by "-".

echo somestring|findstr /r /c:"-KB[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-" >nul

Then use substitution to remove everything from the beginning through "KB-".

Then use FINDSTR to verify that the first 7 remaining characters are digits. If not, then loop back and replace up to the next "-KB", etc.

Then you just need to take the first remaining 7 characters.

@echo off
:parseVal
setlocal enableDelayedExpansion
set val="%~1"
echo !val!|findstr /r /c:"-KB[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-" >nul || (
  echo Invalid format - KB value not found
  exit /b
)
:parseVal2
set "val=!val:*-KB=!"
echo !val!|findstr /brc:"[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-" >nul || goto :parseVal2
set "val=KB!val:~0,7!"
echo val=!val!
exit /b


EDIT

I'm not sure what you did to accept the 6 digit numbers, but the following regex expressions will work with numbers of any length.

For the 1st regex: findstr /rc:"-KB[0-9]*-"
For the 2nd regex: findstr /brc:"[0-9]*-"

Then you can use either of the following to extract out the number when you don't know the length:

for /f "delims=-" %%A in ("!val!") do set "val=KB%%A"

or

set val=KB%val:-=&REM %"

Upvotes: 5

Related Questions