How to delete files matching a certain pattern in their name? - batch-file

I'm creating a batch file that deletes all Rar$DIa0.??? folders in the %TEMP% directory.
Is this possible, and how to do it?
The ??? is three randomized numbers. And that's where I have trouble with - deleting all folders that have Rar$DIa0. in the name.

for /d is designed for just this type of use. Something like this should work (remove one of the % if you're testing from the command line):
for /d %%i in ("%TEMP%\Rar$DIa0.???") do rd "%TEMP%\%%i"
The /d makes it work on directory names instead of file names.
If you want to make it easier on yourself, change to the %TEMP% folder first:
pushdir
cd /d %TEMP%
for /d %%i in ("Rar$DIa0.???") do rd "%%i"
The ??? makes it only act on folders that have three letters after a .. If your folders don't have just a three letter extension, change .??? to .*. If you've got a typo, and there is no actual . in the foldername, just remove it and use Rar$DIa0??? or Rar$DIa0*
You may want to test it first by changing rd to echo to make sure you get the folders you want before actually deleting them.
For more information about for (pun intended) type for /? from a command prompt.

The command line to use in a batch file for this task is:
#for /D %%I in ("%TEMP%\Rar$DIa0.*") do #rd /Q /S "%%I"
Command FOR with option /D searches in folder defined by environment variable TEMP for subfolders with folder name starting with Rar$DIa0. not having hidden or system attribute set.
The loop variable I holds for each found subfolder matching this folder pattern the name of found folder with full path without double quotes although the path to temp folder very often contains 1 or more spaces.
For that reason just the command RD with the parameters /Q for quiet execution and /S for deleting also all subfolders in the specified folder must be called with referencing the current value of loop variable I enclosed in double quotes.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
for /?
rd /?
By the way: WinRAR deletes the temporary folders usually automatically, except a file is opened from within an archive for viewing/modifying it in another application and WinRAR is closed before the other application is exited with the opened file. In this case WinRAR can't delete the temporary folder with temporarily extracted file because the file is still opened in another application. Of course also command RD can't delete the temporary folder if this folder is still the current directory of another application or a file in this folder is still opened by another application with a read/write access lock.

Related

Batch file to remove specific subfolders but move everything inside them to the outside first

I am looking for help with a batch script which can help me remove specific subfolders from all directories that are in the same place as the batch file. But instead of deleting everything in the subdirectory, I want to move the contents outside of the subdirectory first.
To elaborate, I receive files which are always nested inside folders with a very specific pattern:
Every request I receive is in a uniquely named folder which follows no specific pattern (the Job Folder).
Inside every Job Folder, there are two things:
A folder denoting the language the file is in (Lang Folder).
An xml file named "Manifest.xml" which contains instructions and metadata.
There is a folder inside every Lang Folder denoting the brand of the file (Brand Folder).
Inside every Brand Folder is a random assortment of subfolders containing JSON files with various degrees of nesting inside different subfolders.
So a typical request would contain the following structure:
Job Folder/Lang Folder/Brand Folder/...
And I want to transform all folders to follow this structure:
Job Folder/Brand Folder/...
You can see an example below of how the folder structure currently looks and how I would like it to look in the end.
Structure of the folders and files before running the batch file:
French_Job1373
French
BrandA
Subfolder
Example.json
Manifest.xml
German_Job1374
German
BrandB
Subfolder1
Subfolder2
Subfolder3
ExampleFile.json
Manifest.xml
Japanese_Job1375
Japanese
BrandC
Subfolder1
Example.json
Manifest.xml
Korean_Job1376
Korean
BrandC
Subfolder1
Subfolder13
ExampleSrc.json
Manifest.xml
Structure of the folders and files as it should be after running the batch file:
French_Job1373
BrandA
Subfolder
Example.json
Manifest.xml
German_Job1374
BrandB
Subfolder1
Subfolder2
Subfolder3
ExampleFile.json
Manifest.xml
Japanese_Job1375
BrandC
Subfolder1
Example.json
Manifest.xml
Korean_Job1376
BrandC
Subfolder1
Subfolder13
ExampleSrc.json
Manifest.xml
I would like to have a batch file which essentially removes the Lang Folder, pulling everything from inside the Lang Folder one level up.
Following should be taken into consideration:
The file Manifest.xml should not be touched. It should remain inside the Job Folder level.
Everything from the Brand Folder level including the Brand Folder itself should be moved one level up (to the same level where the file Manifest.xml is).
The Language Folder (which at this point should be empty) should be deleted.
There is a finite list of possible languages after which the Lang Folder is named. If required to specify all possible languages in the batch file, I would like the option to add new languages to the list in the future.
So far, I have managed to get the batch file below to work as expected, but I need to run as many times as there are Job Folders and I have to place it inside the Language Folder to have it work as expected. If I place it anywhere else, it just deletes the Lang Folder with all of its contents and does not move anything. I am looking to have the batch file check all folders that are next to it and perform the operation as many times as needed.
What I have so far:
#echo off
if -%1==- echo No parameters! You must add %%P parameter! & pause & goto :EOF
cd /d %1
move * ..
for /d %%f in (*) do move %%f ..
cd ..
"%commander_path%\totalcmd.exe" /o /s %1\..
rd %1
FOR /d /r . %%d IN (Russian) DO #IF EXIST "%%d" rd /s /q "%%d"
FOR /d /r . %%d IN (French) DO #IF EXIST "%%d" rd /s /q "%%d"
FOR /d /r . %%d IN (German) DO #IF EXIST "%%d" rd /s /q "%%d"
FOR /d /r . %%d IN (Japanese) DO #IF EXIST "%%d" rd /s /q "%%d"
That is an excellent description of the folder moving task which can be done with a batch file stored in the folder containing all the Job Folders containing the following lines.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ErrorPause="
for /D %%I in ("%~dp0*_Job*") do for /F "eol=| delims=_" %%J in ("%%~nxI") do if exist "%%I\%%J\" (
for /F "eol=| delims=" %%K in ('dir "%%I\%%J" /A /B 2^>nul') do move "%%I\%%J\%%K" "%%I\" 2>nul || (echo Failed to move: "%%I\%%J\%%K"& set "ErrorPause=1")
rd "%%I\%%J" 2>nul || (echo Failed to delete: "%%I\%%J"& set "ErrorPause=1")
)
if defined ErrorPause pause
endlocal
The first FOR loop searches in folder of the batch file referenced with %~dp0 (path ends always with a backslash) for non-hidden subfolders matching the wildcard pattern *_Job*. So assigned to loop variable I are one after the other the full qualified folder names of the Job Folders French_Job1373, German_Job1374, German_Job1374, Korean_Job1376, ...
The second FOR command splits up the current Job Folder name on underscores with everything up to first underscore assigned to loop variable J. That is the name of the Lang Folder in current Job Folder.
The IF condition checks if the Lang Folder in current Job Folder exists at all as otherwise there is nothing to do for the current Job Folder.
The third FOR loop starts one more command process in background with %ComSpec% /c and the command line within ' appended as additional arguments. So there is executed with Windows installed into C:\Windows and batch file path being C:\Temp, for example, for the first Lang Folder of first Job Folder:
C:\Windows\System32\cmd.exe /c dir "C:\Temp\French_Job1373\French" /A /B 2>nul
The command DIR outputs
all names of the folders and files including hidden ones because of option /A (all attributes)
in bare format because of option /B which means just folder/file name without path
in the specified directory.
FOR ignores folders and files with hidden attribute set which is the reason for using the DIR command line executed by a separate command process in the background.
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
FOR with option /F would split up by default all lines captured from handle STDOUT of background command process after started cmd.exe terminated itself into substrings using normal space and horizontal tab as string delimiters, would ignore next the line if the first substring starts with a semicolon being the default end of line character, and would otherwise assign just the first space/tab separated string to specified loop variable K. That behavior would be no problem according to the example for the folders BrandA, BrandB and two times BrandC. But the usage of the option string "eol=| delims=" results in using a vertical bar as end of line character which no folder/file name can contain and the definition of an empty list of string delimiters which disables line splitting behavior. So each folder/file name output by DIR without path is assigned completely to the loop variable K one after the other.
The command MOVE moves the current folder/file in Lang Folder of current Job Folder one level up into the Job Folder. This action is very fast as this is done by just updating the master file table of the file system which is cached by Windows. There is an error message output and the environment variable ErrorPause is defined if an error occurs on moving a folder or file up one level.
The current Lang Folder is removed with command RD after all folders and files in the current Lang Folder are moved up hopefully successfully. The deletion of the folder fails if a folder or file in Lang Folder could not be moved up because of a file in this folder tree is currently opened by an application, or a folder in this folder tree is the current folder of any running process, or a folder/file with same name exists already in Job Folder. An error message is output and the environment variable ErrorPause is defined on deletion of Lang Folder fails because of the folder is not empty.
The command PAUSE halts the batch file execution until a key is pressed if an error occurred. Otherwise the processing of the batch file ends without requiring any further user action.
The batch file can be simply executed once again in case of an error because of a file is opened in an application, or a folder is the current folder of a running process, or the folder/file to move exists already in Job Folder after closing the file in the application or the application itself respectively deletion of the folder/file in Job Folder.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~dp0 ... drive and path of argument 0 which is the batch file path.
dir /?
echo /?
endlocal /?
for /?
if /?
move /?
pause /?
rd /?
set /?
setlocal /?
All these commands are internal commands of Windows command processor cmd.exe.
See also: Single line with multiple commands using Windows batch file

Why is a folder not deleted with RMDIR in batch file as last command?

I have the following code in a .bat file:
#echo off
xcopy /Y /S %CD%\Code\Release C:\Users\%USERNAME%\Desktop\ShareIt /I
cls
cd C:\Users\%USERNAME%\Desktop\ShareIt\
call "Trabalho AEDA.exe"
xcopy /Y /S C:\Users\%USERNAME%\Desktop\ShareIt\FICHEIROS\ %CD%\Code\Release\FICHEIROS\
RMDIR /S /Q C:\Users\%USERNAME%\Desktop\ShareIt
That copies a folder to a location, runs the .exe from it and then it overwrites the original files in my folder and has do delete the ones initially copied.
The folder I copy to the user desktop has other folder inside, and the .exe.
At the final line of the .bat, it deletes everything in the folder, but the folder is kept in the Desktop folder. I want to delete it, too. I tried several instructions, but without success.
EDIT: That was the issue, thanks guys.
ShareIt folder isn't deleted probably because you are in the folder.
So, adding cd .. before RMDIR /S /Q C:\Users\%USERNAME%\Desktop\ShareIt solves it.
The main problem with deleting ShareIt folder is already answered by the other answers.
It is not possible on Windows to delete a folder which is the current working directory of any running process or in which a file is opened by an application with a file lock preventing the deletion of the opened file.
In this case the ShareIt folder is the current working directory of the command process executing the batch file because the batch file explicitly sets this directory as working directory. The solution is making any other directory the working directory for the command process.
But this is not the only potential problem of the few command lines of this batch file. There are some more.
%CD% could expand to a path which contains perhaps one or more spaces or other characters like &()[]{}^=;!'+,`~ which require enclosing complete folder path in double quotes. This list of characters is output on running in a command prompt window cmd /? in last paragraph on last output help page.
Also %CD% expands to a folder path usually not ending with a backslash, except the current directory is the root directory of a drive. So %CD%\Code\Release could for example expand to C:\\Code\Release with two backslashes in path. However, this is no real problem as Windows kernel corrects the path automatically on whatever file system access function is used internally by xcopy for copying the files and folders.
Parameter /I lets xcopy interpret the target string as folder path even if folder path is not ending with a backslash, but only if multiple files are copied like when source path is a folder path like it is here obviously the case. Otherwise on copying just a single file /I is ignored by xcopy. Best for a folder path as target is specifying the target folder path with a backslash as then xcopy interprets target always as folder path. It is easier to use here paths relative to current directory and omit %CD% completely.
C:\Users\%USERNAME% is not good as the user's profile directory can be also on a different drive than C: and can be in a different directory than Users, for example on Windows XP. The path C:\Users\%USERNAME% is the default for the user's profile directory since Windows Vista. But every user has the freedom to change it also on Windows Vista and later Windows versions. There is the environment variable USERPROFILE defined by Windows which contains full path to active user's profile directory. See Wikipedia article about Windows Environment Variables for more details about predefined Windows environment variables.
And of course the user's profile directory path could contain one or more spaces or other characters which again require double quotes around complete folder path or file name, for example if the user account name contains a space character. So again double quotes should be used wherever %USERPROFILE% or %USERNAME% is used in a folder or file name with path.
Command CD without parameter /D changes the current directory only on current drive if the new current directory exists at all on current drive. So with current directory on starting the batch file being on a different drive than drive C:, changing the current directory with used code would not work at all.
The command CALL should not be necessary at all in case of Trabalho AEDA.exe is really an executable as the file extension indicates. CALL can be used also for an executable, but it is designed primary for running a subroutine or calling another batch file from within a batch file.
The last two lines do not really make sense because the current directory was changed by the batch file to ShareIt folder in desktop folder of current user. Therefore %CD%\Code\Release\FICHEIROS\ expands to
C:\Users\%USERNAME%\Desktop\ShareIt\Code\Release\FICHEIROS\
as target path for xcopy and the last line deletes the entire folder
C:\Users\%USERNAME%\Desktop\ShareIt
That is obviously not the intention. xcopy in last but one line should copy the files to a subdirectory in initial current directory.
I suggest to use this batch code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
%SystemRoot%\System32\xcopy.exe Code\Release "%USERPROFILE%\Desktop\ShareIt\" /C /Q /R /S /Y >nul
pushd "%USERPROFILE%\Desktop\ShareIt"
if not errorlevel 1 "Trabalho AEDA.exe" & popd
%SystemRoot%\System32\xcopy.exe "%USERPROFILE%\Desktop\ShareIt\FICHEIROS" Code\Release\FICHEIROS\ /C /Q /R /S /Y >nul
setlocal EnableDelayedExpansion
if "!CD:%USERPROFILE%\Desktop\ShareIt=!" == "!CD!" RMDIR /S /Q "!USERPROFILE!\Desktop\ShareIt"
endlocal
endlocal
The last IF conditions needs most likely an additional explanation for what is its purpose.
!CD:%USERPROFILE%\Desktop\ShareIt=! results in searching case-insensitive in current directory path string for all occurrences of the path string to ShareIt directory in desktop directory of current user and replacing all found occurrences by an empty string. So it depends on what is the current directory on what happens here.
In case of current directory is %USERPROFILE%\Desktop\ShareIt, the string left of comparison operator == becomes "". In case of current directory is a subdirectory of %USERPROFILE%\Desktop\ShareIt, the string left of == becomes a relative path to this directory enclosed in double quotes. In all other cases the string left of == is not modified at all and expands to path of current directory enclosed in double quotes like the string right of the comparison operator.
So the IF condition checks if the current directory is NOT the ShareIt directory or a subdirectory of this directory in the desktop directory of current user. Only in this case it is safe to delete the entire ShareIt directory.
Note: The IF condition does not work correct on %USERPRFOLE% expands to a folder path string containing one or more ! because of enabled delayed variable expansion.
For understanding all other used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
cd /?
echo /?
endlocal /?
if /?
popd /?
pushd /?
set /?
setlocal /?
xcopy /?
There should be read also the Microsoft documentation about Using command redirection operators for an explanation of >nul.
Since you execute
cd C:\Users\%USERNAME%\Desktop\ShareIt\
It's the current directory when you execute the now delete the directory command.
Move to another directory, and then try the deletion

How to delete multiple files from multiple folders in batch

I was trying to make a batch file that could copy a whole folder (with files and subfolders) inside multiple subfolders placed inside multiple subfolders.
The fact is that I messed up the commands and ended with all the files and subfolders copied where I wanted but not inside a folder.
Now I want to delete all these files and subfolders without deleting the original files from each folder.
I tried this command directly in a command prompt window, but it didn't work and I have no idea why because the input and the loops appear to be right.
for /d %a in (`E:\Mis documentos\Nueva carpeta\Filosofia\*') do for /d %b in ("%a\*") do for %c in ("*") do del %b\%c
This returns "The system cannot find the specified file" but the command executed is del E:\Mis documentos\Nueva carpeta\Filosofia\Some folder\Another folder\The exact file that I want to delete in that folder. What could cause that?
When I do the same but echoing %b/%c it returns the exact path of the items I want to delete from the folders. (Note that I am trying to run this command from inside the folder I wanted to copy in the first place so that I can recover the name of each file independently.)
The best solution is to use the command del with the switches /Q (quiet) and /S (also in all subdirectories) as D.Ddgg suggested already, too.
del /Q /S "E:\Mis documentos\Nueva carpeta\Filosofia\*.txt" "E:\Mis documentos\Nueva carpeta\Filosofia\*.jpg"
Arguments with a space or other special characters like &()[]{}^=;!'+,`~ inside must be enclosed by double quotes. This list of special characters is output on running in a command prompt window cmd /? and looking on last paragraph on last page of the help.

dos command delete folder and files using a wild card character

In a DOS batch command window, I want to delete folders (and corresponding files within that directory) with part of the name that contains the following string (SUB
I want to start at a specfic root directory called C:\app2\proc.
I want to delete the directory and the files contained within the directory.
I want to delete folders where part of the file name is (SUB.
What I have tried so far does not work.
Here is what I have tried to far:
del /f /s /q C:\app2\proc\*(SUB*
Note: the asterik before (SUB and the asterik after (SUB is not showing up in the display of what I have tried to far.
Thus can you tell me how to solve this problem?
You can use a for loop to run through your files and send a variable (%x in this case) to rmdir with your path. Try this:
for /d %x in (*(sub*) do rmdir /s /q c:\app2\proc\%x
You porbably need to escape that ( character so that it does not get evaluated.
Checkout http://www.robvanderwoude.com/escapechars.php it seems you should replace ( with ^(

xcopy does not create directory structure

I have a strange problem with xcopy in Windows XP Professional. I don't know if its a stupid question as I am specifying only a file as the source, so should I even expect any other behavior ? This is it:
I am using xcopy <src> <dest> /s/y.
<src>=C:\sourcefolder\a\b\c\d\something.java and
<dest>=C:\destinationfolder.
Now xcopy copies the file but does not create the directory structure \a\b\c\d\ inside C:\destinationfolder .
what I want is C:\destinationfolder\a\b\c\d\something.java and
what I get is C:\destinationfolder\something.java
I have tried to run it in destination folder C:\destinationfolder by specifying a . for target folder
Tried it without any target in above
There is a script I have which calls xcopy iteratively so I am left with C:\destinationfolder\many java files without any directory structure.
A. Yes I have done xcopy /? to see all options
B. /T also does not create any empty directory structure
C. I can not go to source folder a\b\c\d\ and run xcopy . <dest>
UPDATE
I removed my previous answer on using ROBOCOPY. I believe the following will do what you want using XCOPY.
Assuming your folder structure is like this:
SOURCE = C:\MyJavaStuff\A\B\C\D\something.java
DEST = C:\MyDestination
Run XCOPY like this:
XCOPY C:\MyJavaStuff\something*.java C:\MyDestination /S /E
Note the * in something*.java.
The problem is that you are specifying which file to copy in the source. xcopy won't create the folder structure in this case. However, if you change your call to xcopy to
xcopy *.java C:\myfolder /s/y
it will copy the .java files and the folder structure as well. You need to specify a wildcard for this call to work as you want. If you want only to copy specific files, you will have to adjust the call to xopy, e.g.:
xcopy something.jav* C:\myfolder /s/y
Edit
You say that you get the list of files to copy from another command. If you can output this list of files in a text file, you could do the following:
FOR /F "tokens=* delims=," %F in (d:\test\list.txt) DO xcopy src\%~nxF* .\dest /S /Y
What this command does is read a text file ("d:\test\list.txt" in this case), read every line, and for each file, run xcopy, adding a wildcard at the end of the file name to make sure it creates the folder structure.
I'm assuming here that:
You can get the list of files in a text file, with only the file names (and optinally the paths)
You know the source folder ("C:\sourcefolder" in your example, the folder structure "a\b\c\d" does not need to be known) and can use it in the FOR command.
You can also use the following form:
FOR /F "tokens=* delims=," %F in ('cmd') DO xcopy src\%~nxF* .\dest /S /Y
where cmd needs to be replace with the command you use to generate your list of files to copy.
Note that if you use this FOR command in a batch file, you need to replace %F with %%F (and %~nxF* with %%~nxF*).
I had a look at the xcopy switches and you can copy the directory structure with /T, although that doesn't copy empty directories you can override this with /E. So your command would look like this:
xcopy C:\sourcefolder\a\b\c\d\something.java C:\destinationfolder /T /E /S /Y
Hope this helps!
In order to get C:\destinationfolder\a\b\c\d\something.java XCOPY needs to know how much of C:\sourcefolder\a\b\c\d\something.java to duplicate.
You can use:
C:
cd \sourcefolder
XCOPY something.java* C:\destinationfolder\ /S
Just be aware that this may have the side effect of also copying C:\sourcefolder\oops\something.java to C:\destinationfolder\oops\something.java as well as any other matches for something*.java under C:\sourcefolder\.
It seems to me that xcopy is typically used for copying directory trees, not single files (though it can work). And, xcopy will recreate the directory structure under the source folder in the target folder. If xcopy is given the /i switch, the target folder is assumed to be a directory. It will be created if it does not exist, even if there are multiple parents that need to be created.
You have C:\MyJavaStuff\A\B\C\D\something.java - that is your source. You want to end up with something.java not in C:\destinationfolder, but in C:\destinationfolder\A\B\C\D - so that is your target. You don't even have C:\destinationfolder. That is OK, with /i the entire path will be created.
xcopy /i c:\MyJavaStuff\A\B\C\D\something.java C:\destinationfolder\A\B\C\D
If something.java were the only file under C:\MyJavaStuff, you could also use
xcopy /sei c:\MyJavaStuff C:\destinationfolder
That would recreate the entire tree structure, copying your file. But if there are other files (and folders) under MyJavaStuff they would also be copied.
I have written a very similar batch file using xcopy. Perhaps what I did will help you.
This is the command I used:
xcopy "c:\Data Files\Dave's Data\*.*" "m:\Dave's Data" /R/D /E/H
In this case, Dave's Data on the source contains an entire directory tree containing at least 50,000 files & exceeding 75GB data. It runs perfectly on Windows XP
I found /T was unnecessary as the directory tree is copied. I also found /S was unnecessary as /E copied directories & sub-directories including empty ones. I included /R to copy & overwrite read only files on the destination. /H copied hidden directories. /D copied only newer files. I use this as a daily backup tool for my data.
The only problem I have is while this command will work on Windows 7 the first time, it will not work on subsequent runs when the destination directory tree exists. I suspect this is due to a privilege issue as the xcopy command will work on subsequent runs on Windows 7 within a cmd.exe window.

Resources