Delete files that don't have special character ® in name or path

2

1

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

root

Posted 2019-11-09T13:05:39.423

Reputation: 272

1For Pete’s sake. Use powershell. It’s a one liner. – Appleoddity – 2019-11-09T14:39:22.430

Answers

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

FastEthernet

Posted 2019-11-09T13:05:39.423

Reputation: 3 385

I get Get-ChildItem : A parameter cannot be found that matches parameter name 'File'. – root – 2019-11-09T13:30:14.343

3@root What version of PowerShell are you on? $PSVersionTable.PSVersion – FastEthernet – 2019-11-09T13:49:24.803

version 2.0.-1.-1 – root – 2019-11-09T14:27:05.037

4@root update your powershell. Download the latest version of Windows management framework for your version of Windows. – Appleoddity – 2019-11-09T14:41:22.527

1@root - add a test for -not $_.PSIsContainer to the Where-Object scriptblock. that works for ps2 ... [grin] – Lee_Dailey – 2019-11-09T19:32:12.723

@Lee_Dailey What exactly would the entire line then look like? – root – 2019-11-10T11:18:41.843

@root See my updated answer. – FastEthernet – 2019-11-10T12:59:16.440

@root - the W-O scriptblock can have more than one test - just like any IF test. so you simply add an -and plus the next test. just like what FastEthernet put in the last code line of his updated answer. [grin] – Lee_Dailey – 2019-11-10T17:52:01.597

The script should descend recursively into subdirectories. (Note that the question had dir /s and that it's about the path, not only the file name, otherwise it would be trivial: Search for *®*.* in explorer, move found files elsewhere, delete remaining files.) I added -Recurse to the answer, waiting for peer review of the edit. – root – 2019-11-11T13:56:24.887

@root Edits shouldn't be made to add parameters missing from a command in another user's answer... such input would be appropriate as a comment, but not as an edit. – JW0914 – 2019-11-16T14:27:24.043

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


It Wasn't Me

Posted 2019-11-09T13:05:39.423

Reputation: 851

What is \M\S? shouldn't the entire findstr part be removed? What is ~fi? – root – 2019-11-10T11:25:18.080

@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 – 2019-11-10T12:21:06.353

@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 – 2019-11-11T00:59:44.230

great detailed answer +1, but IMO super complex compared to a PowerShell oneliner – SimonS – 2019-11-11T07:12:47.050

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 – 2019-11-11T13:46:51.523

@root I think the user's here, won't like see multiple answer post by same user, if, can put one with many options so solve a question hope you understend me. – It Wasn't Me – 2019-11-11T13:50:47.250

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

Ricardo Bohner

Posted 2019-11-09T13:05:39.423

Reputation: 1 256