I have seen How to delete all files that don't have a certain string in their name

However, I would like to delete files that do not have a certain string in their filename or path (not only filename), and I would like that string to be the character ®.

Based on this revision history, the following works for the string "MS", but not for special characters:

@echo off
setlocal disableDelayedExpansion
for /f "usebackq tokens=*" %%i in (`dir /a:-d /b /s *.zip ^| findstr /v MS` ) do (
  echo del /s /q %%i
  • 1
    For Pete’s sake. Use powershell. It’s a one liner. – Appleoddity Nov 9 at 14:39
# ®
$specialChar = [char]0x00AE
Get-ChildItem -File -Recurse | Where-Object {!$_.FullName.Contains($specialChar)} | Remove-Item

For older versions of PowerShell that does not support the -File parameter, use:

Get-ChildItem -Recurse | Where-Object {!$_.FullName.Contains($specialChar) -and -not $_.PSIsContainer} | Remove-Item
  • I get Get-ChildItem : A parameter cannot be found that matches parameter name 'File'. – root Nov 9 at 13:30
  • 2
    @root What version of PowerShell are you on? $PSVersionTable.PSVersion – FastEthernet Nov 9 at 13:49
  • version 2.0.-1.-1 – root Nov 9 at 14:27
  • 3
    @root update your powershell. Download the latest version of Windows management framework for your version of Windows. – Appleoddity Nov 9 at 14:41
  • 1
    @root - add a test for -not $_.PSIsContainer to the Where-Object scriptblock. that works for ps2 ... [grin] – Lee_Dailey Nov 9 at 19:32

• The short option in cmd/bat:

:: in command line :: 
chcp 1252 >nul & for /f "tokens=*" %i in ('dir /a:-d /b /s *.zip ^|find /v "®"')do echo=del /q /f "%~fi"

:: in cmd/bat file ::
@echo off && >nul chcp 1252

for /f "tokens=*" %%i in ('dir /a:-d /b /s *.zip ^|find /v "®"')do echo=del /q /f "%%~fi"

  • My directory tree for test in G:\SUPER_USER\Q1500545:

¦   Q1500545.cmd
¦       test_º.zip
¦       test_¿.zip
¦       test_®.zip
¦       test_®.zip
¦       test_º.zip
¦       test_¿.zip
¦       test_®.zip
¦       test_º.zip
¦       test_¿.zip

  • My script results by echo/del /f /q "%~1":

del /f /q "G:\SUPER_USER\Q1500545\Sub_Dir_01\test_º.zip"
del /f /q "G:\SUPER_USER\Q1500545\Sub_Dir_01\test_¿.zip"
del /f /q "G:\SUPER_USER\Q1500545\Sub_Dir_02\test_º.zip"
del /f /q "G:\SUPER_USER\Q1500545\Sub_Dir_02\test_¿.zip"
del /f /q "G:\SUPER_USER\Q1500545\Sub_Dir_03\test_º.zip"
del /f /q "G:\SUPER_USER\Q1500545\Sub_Dir_03\test_¿.zip"

Obs.: To add ® in your code, try...

  • Press and holding the alt (left) + (num pad) 1 6 9

enter image description here

enter image description here

enter image description here

  • What is \M\S? shouldn't the entire findstr part be removed? What is ~fi? – root Nov 10 at 11:25
  • @root This is just a simple use for an escape: Literal M Literal S, it's good for the root user to know that! – It Wasn't Me Nov 10 at 12:21
  • @root %%~fi Is for token the Full path of file in variable loop %%i, in this case, the zip file listed by dir command. – It Wasn't Me Nov 11 at 0:59
  • 1
    Your post consists of several answers. Please split them into separate answers. We can then discuss each answer individually in the comments, upvote each answer individually, etc. – root Nov 11 at 13:46
  • 1
    Please have a look at meta.stackexchange.com/questions/25209/… – root Nov 11 at 14:39

Batch is not unicode compatible so it recognizes ® as © so I just changed ® with © in the batch file but I guess changing the code page with chcp also works. Do you want to delete all files that don't have the ® in the name or only zip files? Well if it's all files just change *.zip to * in the for:

@echo off
Title Delete all files that don't have © in Name
setlocal EnabledelayedExpansion

Rem Specify the path to the folder here:
set Folder=%userprofile%\desktop\test

for /r %Folder% %%a in (*.zip) do (
set Character=%%a
set Character=!Character:©=!
IF "!Character!"=="%%a" del /a /f "%%a"

Maybe this can help?

In fact the special console character, where it activates the page and encodes it used to write / read the file name, and moves that information to variables, read and compare it all in alphabet soup, is a bit difficult to handle in cmd/bat, which is why I asked for help for a language...

Therefore, for a paranoid proposal, considering actions for delete files, I took C# to try implemented a comparison using base64 for string (wildcard alt 169 = ®).

  • Obs.: 169 = ® and differs from the 0169 = ©

The resulted from these actions, is a script cmd/bat, that at run time compiles the one C# sources into a executable, that will be used by script, to get string from file name, whether the character name is present (in base64) in the name.

Is this my friend, or, is something completely different from exposed above, and, that my English limited prevent me to explain to you clearly :)

  • The script cmd/bat:

@echo off && setlocal EnableExtensions EnableDelayedExpansion & chcp 1252 1>nul

cd /d "%~dp0" && set "_.net=%windir%\Microsoft.NET " && title < nul && title Q1500545.cmd 
set "_arg=/t:exe /out:"%temp%\b64.exe" "%temp%\b64.cs" /platform:anycpu /unsafe+ /w:0 /o"
set "_here=." type nul >"%temp%\b64.cs" && set "_b64=%temp%\b64.exe" && >"%temp%\b64.cs"^
    echo/ using System^;namespace b64 ^{class Program ^{static void Main^(string[] args^)
    echo/ ^{if ^(args.Length ^> 1 ^&^& args[0] ^=^= "-e" ^| args[0] ^=^= "-E"^)
    echo/ ^{byte[] plainTextBytes ^= System.Text.Encoding.UTF8.GetBytes^(args[1]^)^;
    echo/ Console.Write^(System.Convert.ToBase64String^(plainTextBytes^)^)^;
    echo/ ^}else if ^(args.Length ^> 1 ^&^& args[0] ^=^= "-d" ^| args[0] ^=^= "-D"^)
    echo/ ^{byte[] base64EncodedBytes ^= System.Convert.FromBase64String^(args[1]^)^;
    echo/ Console.Write^(System.Text.Encoding.UTF8.GetString^(base64EncodedBytes^)^)^;
    echo/ ^}^}^}^} 

for /f delims^=^ eol^=* %%i in ('%__APPDIR__%where.exe /r "!_.net!" "csc.exe"^|findstr /li k\v2\.
')do "%%~i" !_arg! /nologo && cd /d "%~dp0" && goto :^?

for /f delims^=^ eol^=* %%i in ('%__APPDIR__%where.exe /r "." "*.zip"')do call :^[ %%~fi
(for %%D in (exe,cs)do del /q "%temp%\b64.%%D") & endlocal && exit /b 

for /f tokens^=* %%a in ('"cmd /u /c echo=%~1|find /v """
')do "!_b64!" -e %%~a|findstr "wq4=" >nul && exit /b )
echo/del /f /q "%~1" && exit /b 

  • My C# code:

using System;
namespace b64 

   class Program 
      static void Main(string[] args)
         if (args.Length > 1 && args[0] == "-e" | args[0] == "-E")
            byte[] plainTextBytes = System.Text.Encoding.UTF8.GetBytes(args[1]);

           else if (args.Length > 1 && args[0] == "-d" | args[0] == "-D")
             byte[] base64EncodedBytes = System.Convert.FromBase64String(args[1]);

  • My command line used to compile code C#:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe /out:"%Temp%\b64.exe" "%Temp%\b64.cs" /platform:anycpu /unsafe+ /w:0 /o


This is in one line, using Powershell, but, not sure if will working as you espect in your PowerShell version:

Get-childitem -re . | Where-Object {$_ -NotMatch '(?:®)'}|remove-item -recurse -force -Confirm:$false

# Or, by using alias #
gci -re . | ? {$_ -NotMatch '(?:®)'}| rd -re -force -Confirm:$false

  • What does the -re option do? I didn't find it here. What is the difference between putting -Recurse after Remove-Item like you do vs. after Get-ChildItem like here? Why are you not sure whether it will work? – root Nov 11 at 20:31
  • @root There only alias, you can try by your self this code: gci -re . | ? {$_ -NotMatch '(?:®)'}| rd -re -force -Confirm:$false – It Wasn't Me Nov 11 at 20:56
  • @root Why are you not sure whether it will work?, I prefer say that, prevent me to affirm that work, but, case not work, here different, even this work.But, I don't have same Powershell for test this code in same version as you have there.. Only this. – It Wasn't Me Nov 11 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.