windowspowershellbatch-filebatch-processing

How to input regular expression, in a batch script written for the Windows command prompt?


Below the script counts the files in the source directory and performs different actions based on the count and the filename. If there are two or more files, it exits with a code of 2. If there are no files, it exits with a code of 0. If there's exactly one file, it checks if the filename is "MT569." If it is, the file is copied to the target directory, and the script exits with a code of 1. If the filename is not "MT569," it exits with a code of 3.

@echo off
setlocal enabledelayedexpansion

set "sourceDir=C:\Users\tar\Desktop\inbound"
set "targetDir=C:\Software\components\data\GateIn\in"
set "count=0"

for %%I in ("%sourceDir%\*.*") do (
    set /a "count+=1"
    set "filename=%%~nI"
)

if %count% geq 2 (
    exit /b 2
) else if %count% equ 0 (
    exit /b 0
) else if %count% equ 1 (
    for /f %%A in ('powershell -command "[System.Text.RegularExpressions.Regex]::IsMatch('!filename!', 'YourPattern')"') do (
        if %%A equ 1 (
            xcopy /y "%sourceDir%\!filename!.*" "%targetDir%"
            exit /b 1
        ) else (
            exit /b 3
        )
    )
)

endlocal

Question - and this is where basically I am stuck and need your help. Instead of using of filename as "MT569" , I am rather expecting below sort of file. COLLAT.CONFIDENTIAL.20231013125640.NO-ACCT.416.ISO

Therefor I am trying to use regular expression "COLLAT.CONFIDENTIAL.\d{14}.NO-ACCT.\d{3}.ISO" in my batch script, however In a standard Windows batch script, I think I cannot use regular expressions directly.

Can someone help me fix this issue please?

Thanks,

I don't know the solution


Solution

  • A streamlined solution:

    @echo off & setlocal
    
    set "sourceDir=C:\Users\tar\Desktop\inbound"
    set "targetDir=C:\Software\components\data\GateIn\in"
    
    :: Count the files of interest and save the name of the last file found.
    set count=0
    for %%f in ("%sourceDir%\*.*") do set /a count+=1 & set "filename=%%~nf"
    
    :: Exit with code 0, if there are no files,
    :: and with code 2, if there are 2 or more.
    if %count% EQU 0 exit /b 0
    if %count% GEQ 2 exit /b 2
    
    :: There is only one file - check if its name matches the regex; 
    :: if not, exit with code 3.
    powershell -c "if ($env:filename -notmatch '^COLLAT\.CONFIDENTIAL\.\d{14}\.NO-ACCT\.\d{3}\.ISO$') { exit 1 }" || exit /b 3
    
    :: The name matches the regex: copy the file to the destination 
    :: and exit with code 1.
    xcopy /y "%sourceDir%\%filename%.*" "%targetDir%"
    exit /b 1
    

    Note: