2

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
)
endlocal
1
  • 1
    For Pete’s sake. Use powershell. It’s a one liner. Nov 9, 2019 at 14:39

3 Answers 3

3
# ®
$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
11
  • I get Get-ChildItem : A parameter cannot be found that matches parameter name 'File'.
    – root
    Nov 9, 2019 at 13:30
  • 3
    @root What version of PowerShell are you on? $PSVersionTable.PSVersion Nov 9, 2019 at 13:49
  • version 2.0.-1.-1
    – root
    Nov 9, 2019 at 14:27
  • 4
    @root update your powershell. Download the latest version of Windows management framework for your version of Windows. Nov 9, 2019 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, 2019 at 19:32
1


Update - Using Powershell:


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

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


• There also, can be more short 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 previous answer with whose probable use is doubtful, but work too!:

@echo off & >nul chcp 1252 

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

Or in commandline ::

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

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

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

enter image description here


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 
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 directory tree for test in G:\SUPER_USER\Q1500545:

G:.
¦   Q1500545.cmd
¦
+---Sub_Dir_01
¦       test_º.zip
¦       test_¿.zip
¦       test_®.zip
¦
+---Sub_Dir_02
¦       test_®.zip
¦       test_º.zip
¦       test_¿.zip
¦
+---Sub_Dir_03
¦       test_®.zip
¦       test_º.zip
¦       test_¿.zip
¦
+---Sub_Dir_04_®
        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"


  • 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]);
            Console.Write(System.Convert.ToBase64String(plainTextBytes));

         }  
           else if (args.Length > 1 && args[0] == "-d" | args[0] == "-D")
         {  
             byte[] base64EncodedBytes = System.Convert.FromBase64String(args[1]);
             Console.Write(System.Text.Encoding.UTF8.GetString(base64EncodedBytes));
         }
      }
   }
}


  • 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



enter image description here


enter image description here


7
  • What is \M\S? shouldn't the entire findstr part be removed? What is ~fi?
    – root
    Nov 10, 2019 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!
    – Io-oI
    Nov 10, 2019 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.
    – Io-oI
    Nov 11, 2019 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, 2019 at 13:46
  • 1
    Please have a look at meta.stackexchange.com/questions/25209/…
    – root
    Nov 11, 2019 at 14:39
0

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"
)
pause

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .