How to delete multiple files from multiple folders in batch - batch-file

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.

Related

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 files matching a certain pattern in their name?

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.

Batch Script to Rename JPEGS adding a 1 to the end

I have a large amount of JPEGs inside subfolders that I need to rename to their current name with an extra 1 at the end.
For example:
G:\FILENAME\Subfolder1\subfolder2\JPEGNAME.JPG
Want to rename to
G:\FILENAME\Subfolder1\subfolder2\JPEGNAME1.JPG
I have over 900 files in this format that I need to rename.
Any help?
edit I added /r as I see you have a tree of files to modify. Type this command in the main holding folder of the JPG files.
Here's a cmd prompt command. Delete the echo if you like what you see on the console.
for /r %a in (*.jpg) do echo rename "%a" "%~na1%~xa"
There may not be a need for anything more than a simple REN command. See How does the Windows RENAME command interpret wildcards?.
As long as none of your file names have multiple dots in the name, then the following should work for the current directory. Just make sure there are at least as many ? as the longest name.
ren *.jpg ??????????????????????????????????????1.jpg
Or to process the entire directory tree
for /r %F in (.) do #ren "%F\*.jpg" ??????????????????????????????????????1.jpg
Or you can iterate each file with a FOR or FOR /R loop and rename them one at a time as foxidrive does in his answer.
using renamer:
$ renamer --find '/(.*)\.JPG/' --replace '$11.JPG' *
to operate recursively, change the * at the end of of the command to **.

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 ^(

Move all files except some (file pattern) from a DOS command

From a DOS command I want to move all files that do not match a file name pattern.
Something like this:
For example I want to move all files that do not start with "aaa"
for %i in (*) do if not %i == aaa* move %i .\..
XCOPY is designed to work with 'exclude' lists... See below:
dir /b /a-d "source"|findstr /b "aaa" >"%temp%\aaafiles.tmp"
xcopy "source" "destination\" /exclude:%temp%\aaafiles.tmp /y
The first line performs a DIR (directory) listing of the source folder, listing files in bare format (/b) ignoring directory names (/a-d). The output is piped into the FINDSTR command.
FINDSTR looks at each filename and compares it's beginning (/b) with the string "aaa".
If the start of a filename matches the string "aaa", the filename is redirected (written) to the file aaafiles.tmp in the users TEMP directory.
The /b is vital because you don't want to exclude files such as theaaafile.txt.
The XCOPY command copies files from the source folder to the destination folder except files that are listed in aaafiles.tmp.
Prompting to overwrite existing files (/y) is turned off.
source and destination will need to be replaced your own foldernames.
Robocopy is a possibility
robocopy source destination *.* /mov /XF aaa*.*
for options see here http://technet.microsoft.com/en-us/library/cc733145.aspx
If you don't mind fiddling with the archive bit, you can use it to selectively copy and delete files based on a file mask.
Move (copy and delete) all files except those beginning w/"aaa" from current directory to "dest". May also specify full source path.
attrib +a *.*
attrib -a aaa*.*
xcopy /a [or /m] *.* dest
del /aa /q *.*
One way you can do it is create a list of the files to move in a temporary file. Then use the file in with the for command. Generate the list using findstr.
> dir/b/a-d | findstr /v aaa* > "%temp%\#movelist"
> for /f %f in (%temp%\#movelist) do move %f ...
The first command gets a list of all files (with no directories) in the current directory and then pipes the list to findstr which excludes (/v) filenames that match the pattern and puts it in the file #movelist in the temp directory. The second command just takes those results so you may do what you will with them (move it).
There's probably a better way to do it in a single command without the temporary file, I just don't know how to write it. I'm not sure how to call the dir command from within the for command. AFAIK it only takes program files that exist, not builtin commands.
In some cases it can be made more simple. For example, I had to copy recursively a bunch of directories but excluding all images (png and bmp files), so I simply created an excludeList.txt file containing:
.png
.bmp
and run
xcopy /S /I <source> <dest> /exclude:c:\excludeList.txt
It will match any file or directory containing .png, but not necessarily ending by .png. (I did not investigate if smart use of wildcards or regular expressions are possible).
It does not handle your particular example (for which you have already a good answer) but it solved my problem, and this page is what I found when I googled in search of a solution :)
Not ideal, but moving all files to the destination and moving the files back to the source is a fast way with actual move operation (no copies). Of course this assumes there are no files in destination matching the wildcard.
move source\*.* destination\ && move destination\aaa*.* source\

Resources