I was trying to copy a file out of a folder and then afterward delete the folder. I'm using RoboCopy on windows 10.
Now I realize I could use the /MOVE switch but I ran into an error doing it the first way I was trying and I'd like to figure it out just so I have the knowledge of why it's happening.
I have a folder structure like so:
ParentFolder
---->SubFolder
-------->test.txt
---->test.bat
From within ParentFolder I run test.bat which contains the following script
echo off
setlocal
set dir="path\to\ParentFolder"
cd %dir%
robocopy %dir% %dir%\.. test.txt
if %ERRORLEVEL% LSS 8 (
rmdir /s /q "%dir%"
)
endlocal
The copy works fine, without the rmdir, the file copies and the old file is left within SubFolder. When I add the rmdir line, the copy still works fine, the old file is actually deleted, but then when it tries to remove the SubFolder directory I get the error that the process cannot access the file because it is being used by another process.
So the final structure looks like this instead of having SubFolder removed:
ParentFolder
---->SubFolder
---->test.bat
---->test.txt
Try this:
echo off
setlocal
set dir="path\to\ParentFolder"
cd %dir%
robocopy %dir% %dir%\.. test.txt
if %ERRORLEVEL% LSS 8 (
cd\
rmdir /s /q "%dir%"
)
endlocal
I think the problem is that you're trying to delete the folder while inside it.
See this example
cd c:\temp\test
rmdir /s /q c:\temp\test
cd c:\temp
rmdir /s /q c:\temp\test
As you can see the first rmdir failed but the second succeeded.
Related
I have a script to delete all files in my Epson Scans Folder. If I run the script manually it works perfectly. But for some reason if I set up a task in task scheduler it does not delete the files? Does anyone know why this would happen?
Note: pclist.txt is just a list of pc names
#echo off
for /F %%G in (pclist.txt) do (
pushd "\\%%G\C$\Epson Scans" || exit /B 1
for /D %%I in ("*") do (
rd /S /Q "%%~I"
)
del /Q "*"
popd
)
Are you sure that the file pclist.txt is located in 'probably' the \Windows\system32 directory?
When run as a Scheduled task the current directory will not necessarily be that used when run as a user.
The easiest way to achieve that is is to put that full path within those parentheses or to add the following line just beneath the #echo off.
IF "%CD%\" NEQ "%~dp0" PUSHD "%~dp0"
For this type of directory structure:
\\rdwlhsdevserver\root\user1\folders\testdat.txt
\\rdwlhsdevserver\root\abhay\testdat.txt
\\rdwlhsdevserver\root\testuser\folders1\folder2\testdat.txt
\\rdwlhsdevserver\root\devadmin\input\testdat.txt
\\rdwlhsdevserver\root\admin\testdata\testdat.txt
I know that I can use del /s /q \\rdwlhsdevserver\root\* to delete files from parent folder and all sub-folders. But I want to delete all folders and files except \\rdwlhsdevserver\root\<folder>\.
After running cmd output should be like:
\\rdwlhsdevserver\root\user1\
\\rdwlhsdevserver\root\abhay\
\\rdwlhsdevserver\root\testuser\
\\rdwlhsdevserver\root\devadmin\
\\rdwlhsdevserver\root\admin\
pushd "\\rdwlhsdevserver\root" && (
for /d %%a in (*) do ( cd "%%a" && ( 2>nul rmdir . /s /q & cd .. ) )
del /f /q *
popd
)
This will change the current active directory (pushd) to the target directory and if there are no problems (conditional execution operator &&) for each folder (for /d) change to it (cd), remove its contents (rmdir) and return to the parent folder. Once done, remove (del) the files inside the root folder and restore the initial active directory.
Why not change the inner for to for /d %%a in (*) do rmdir "%%a" /s /q ? Because this will also remove the folder. But if we first make the folder the current active directory (cd) we will be able to delete its contents but not the folder itself as it is in use (the 2>nul is a redirection of the stderr stream to nul to hide the error in the rmdir saying it can not remove the folder because it is in use)
You need to iterate over all sub-directories of \\rdwlhsdevserver\root\ using a for /D loop, then loop over each sub-directory's sub-directories again by another for /D loop, then apply the rmdir (or rd) command on each of the returned items, like this:
for /D %%J in ("\\rdwlhsdevserver\root\*") do (
for /D %%I in ("%%~J\*") do (
rmdir /S /Q "%%~I"
)
)
Or in command prompt directly:
for /D %J in ("\\rdwlhsdevserver\root\*") do #for /D %I in ("%~J\*") do #rmdir /S /Q "%~I"
For the sake of overall performance, if you want to delete directories and files, I recommend to do the above directory removal before the file deletion (del /S /Q "\\rdwlhsdevserver\root\*"). Note that your del command line also deletes files located in the directory \\rdwlhsdevserver\root\.
I have a folder C:\Epson Scans, I am trying to figure out how to write a script that will delete the contents of the folder but leave the folder intact. I have figured out how to delete the entire folder and I could recreate it. But I wanted to know if anyone knows a way of just deleting the contents inside the folder and not actually deleting the folder. Any help with this would be greatly appreciated!
Edit: Inserting working code so I can loop through many computers and do it at once. Will someone please tell me why the code is not working where I have inserted it?
#echo off
setlocal enabledelayedexpansion
set Delete_success=0
set total=0
for /F %%G in (pclist.txt) do (
set /a total+=1
pushd "C:\Epson Scans" || exit /B 1
for /D %%I in ("*") do (
rd /S /Q "%%~I"
)
del /Q "*"
popd
if !ERRORLEVEL!==0 (
set /a Delete_success+=1
) else (
echo EpsonDelete copy failed on %%G>>EpsonDelete_FailedPCs.txt
)
)
echo Delete Success: %Delete_success%/%total% >>EpsonDelete_FileCopy.txt
del deletes files only, so del /S /Q "C:\Epson Scans" deletes all files in the given folder and sub-folders (due to /S).
rmdir deletes folders, so specifying rmdir /S /Q "C:\Epson Scans" also deletes the folder Epson Scans itself.
Of course you could execute mkdir "C:\Epson Scans" afterwards to newly create the deleted folder again1, but this was not asked for. So the correct answer is to use a for /D loop over C:\Epson Scans and delete each folder it contains, and then use del /Q to delete the files:
pushd "C:\Epson Scans" || exit /B 1
for /D %%I in ("*") do (
rd /S /Q "%%~I"
)
del /Q "*"
popd
Note that rd is the same as rmdir -- see also this post: What is the difference between MD and MKDIR batch command?
1) Regard that some folder attributes get lost if you do that, for example the owner. Also the case is lost as Windows treats paths case-insensitively.
del /S C:\Epson Scans*
(use S to delete all files and folders in selected folder)
del C:\Epson Scans*.*
if this is batch file you might want to add /Q in order to avoid a delete confirmation dialog:
del C:\Epson Scans\*.* /Q
I have made a bat script as follows
cd "D:\ACT\ACTBKUP"
del /Q *.*
FORFILES /P E:\ACT_Backups /M *.zip /D +1 /C "cmd /c del #D:\ACT\ACTBKUP"
The script is supposed to delete everything in "D:\ACT\ACTBKUP" and then move the newest zip folder to that same folder from E:\ACT_Backups. When I run this script from windows server 2012 it just disappears.
thanks
In order to switch to a directory that is located on a different drive, you need to use cd /d instead of just cd. If you do not do this, the directory will not change.
When you run a script by double-clicking on it, batch considers the current directory to be the directory where the script is currently located. Since you are not using the /d option with cd, you are running del /Q *.* on the directory where the script is located.
To fix this, you have two options:
cd /d "D:\ACT\ACTBKUP"
del /Q *.*
or
del /Q "D:\ACT\ACTBKUP"
There is no option in forfiles to get just the most recent file; /D +1 will return all files with a last-modified date of today or later. In order to get the most recent file and nothing else, you will need a for /f loop:
rem /b returns just the file name and /o:d sorts the files by date
rem Since newest_file gets set for each .zip file in the directory,
rem the last file set will be the newest
for /f "delims=" %%A in ('dir /b /o:d E:\ACT_Backups\*.zip') do set newest_file=%%A
copy %newest_file% D:\ACT\ACTBKUP
I'm trying to clear a folder of all it's contents but a certain sub-folder and its contents. My deleting works fine but I can't figure out how to exclude.
cd C:\testfolder
del * /S /Q
rmdire /S /Q "C:\testfolder"
But I do not want to delete the folder C:\testfolder\subf. How can I do this?
If you are using at least windows vista (robocopy command is used), this should do the job
#echo off
setlocal enableextensions disabledelayedexpansion
rem Create a temporary empty folder
set "tempFolder=%temp%\%~nx0.%random%%random%%random%.tmp"
md "%tempFolder%" >nul 2>nul
rem Purge from target folder anything not in the empty source folder,
rem but exclude the indicated folder
robocopy "%tempFolder%" "c:\testfolder" /nocopy /purge /xd "c:\testfolder\subfolder"
rem Cleanup
rmdir "%tempFolder%" /s /q >nul 2>nul
If you mean you want to delete all files but not the subfolder you can just use the following
cd C:\testfolder
del *.* /S /Q
This will delete any files in the "testfolder" and any files in the subfolders but will leave the subfolder there.