Search code examples
regexwindowsbatch-filedos

Batch file - Deleting files with a name matching this regex OR that regex but NOT that one


I try to write a Windows batch file to delete all files in a directory matching ((regex1 or regex2) and not regex3).

I'm able to delete files matching a regular expression using something like:

for /f "tokens=*" %%a in (
    'dir /a-d /b *.* ^| findstr /r /c:"^test[0-9]*.jar$"'
) do del "%%a"

But I have no idea how I can say :

  1. this regex or this one.
  2. but not this one

~~~

UPDATE

A better example of what I'm trying to do :

The .bat file would be automatically ran at the end of the extraction of a 7-zip's SFX (self-extracting) executable. This executable will update some versioned jars inside a folder structure.

Let's say the executable will extract a test-1.0.2.jar file inside a lib folder. If this exact file (same version) already exists, then it is overwritten, this already works well since it is managed by the SFX executable itself. But if there already are other versions of the same file in the lib folder, I want the .bat file to delete them! For example :

  • test-1.0.1.jar
  • test-1.0.3.jar
  • test-1.0.jar
  • test-1.jar
  • test.jar

...would have to be deleted.

But those must not be deleted :

  • test-1.0.2.jar (the new file itself)
  • test-test2-1.0.0.jar (not a version of the same file)

I'm currently not able to express that using only one regex in the .bat , because findstr's regex capabilities are pretty limited. But if I was able to say :

Anything that is :

  • ^test.jar$ or
  • ^test-[0-9]+.jar$ or
  • ^test-[0-9]+.[0-9]+.jar$ or
  • ^test-[0-9]+.[0-9]+.[0-9]+.jar$

... must be deleted except :

  • test-1.0.2.jar

Then it would work.

Any idea?


Solution

  • If you want to preserve the most recent version, then I should think you would want to preserve test-1.0.3.jar, not test-1.0.2.jar. But I'll assume you know what you are doing.

    This is easily solved using my JREN.BAT hybrid JScript/batch utility. JREN.BAT is pure script that runs natively on any Windows machine from XP onward.

    JREN.BAT is really is intended to rename files (or folders) via regex replacement. But there is a /LIST option that simply lists the result, without actually renaming anything. The /RFM option specifies a regex file mask to determine which files are to be included. The /FX option is used to specify an exclusion list.

    from the command line:

    for /f "delims=" %F in ('jren "^" "" /list /fx "test-1.1.2.jar" /rfm "^test(?:-\d+(?:\.\d+)*)?\.jar$"') do del "%F"
    

    Or from within a batch script:

    @echo off
    for /f "delims=" %%F in (
      'jren "^" "" /list /fx "test-1.1.2.jar" /rfm "^test(?:-\d+(?:\.\d+)*)?\.jar$"'
    ) do del "%%F"
    

    Update in response to comment

    To delete files from "%dp0lib" (see OP's comment), you could use (note that %dp0 already ends with \):

    @echo off
    for /f "delims=" %%F in (
      'jren "^" "" /list /fx "test-1.1.2.jar" /rfm "^test(?:-\d+(?:\.\d+)*)?\.jar$" /p "%~dp0lib"'
    ) do del "%~dp0lib\%%F"
    

    or

    @echo off
    pushd "%~dp0lib"
    for /f "delims=" %%F in (
      'jren "^" "" /list /fx "test-1.1.2.jar" /rfm "^test(?:-\d+(?:\.\d+)*)?\.jar$"'
    ) do del "%%F"
    popd
    

    Final update to support spaces in path when PATH does not point to jren

    @echo off
    for /f "delims=" %%F in (
      '^""%~dp0jren.bat" "^" "" /list /fx "test-1.1.2.jar" /rfm "^test(?:-\d+(?:\.\d+)*)?\.jar$" /p "%~dp0lib"^"'
    ) do del "%~dp0lib\%%F"