Ok. I have this batch file that is designed to remove every file and folder from inside a folder that may or may not be present. The basic structure Follows:
#echo off
If EXIST c:\MyDirectory\(
chdir c:\MyDirectory\
echo %CD%
echo %0
echo %~dp0
rem ... This removes everything from the folder....
for /F "delims=" %%i in ('dir /b') do (rmdir "%%i" /s/q || del "%%i" /s/q)
)
The reason for the echoes in I'd like to be able to ensure the batch script has actually changed the path to MyDirectory and is deleting the correct files(we had an incident earlier that I'm kindof in hot water for where the script didn't change paths and deleted everything from one of our docs folders).
The echoes return the either the name of the batch file itself, or the path the batch file was run from,instead of "c:\MyDirectory\". So in my case it's from c:\Testing\ (a dummy directory I created to avoid a second oops).
Is there a way to get the currently active directory from inside a batch script, so that I can verify the directory I'm about to empty??
Try this:
#echo off
setlocal EnableDelayedExpansion
If EXIST c:\MyDirectory\(
chdir c:\MyDirectory\
echo !CD!
pause
rem ... This removes everything from the folder....
for /F "delims=" %%i in ('dir /b') do (rmdir "%%i" /s/q || del "%%i" /s/q)
)
Since you're in an if statement you should use setlocal EnableDelayedExpansion and use ! instead of % for variables.
To nuke the contents of a directory, use this shell script (batch file):
#echo off
setlocal enableextensions
if {%1}=={} goto :HELP
if {%1}=={/?} goto :HELP
goto :START
:HELP
echo Usage: %~n0 directory-name
echo.
echo Empties the contents of the specified directory,
echo WITHOUT CONFIRMATION. USE EXTREME CAUTION!
goto :DONE
:START
pushd %1 || goto :DONE
rd /q /s . 2> NUL
popd
:DONE
endlocal
Related
Based on several articles on the internet I have written a batch script that:
scans defined location looking for .png files,
creates path to the new location for each file (..\first 4 characters of filename\first 9 characters of filename)
moves files to the new location
The script works fine, however I would like it to stop displaying errors and commands in command line window and display "PROCESSING..." instead? I have tried echo off, >nul and 2>nul with no success.
Here's the script:
#echo off
setlocal enabledelayedexpansion
cls
pushd E:\Archiwum\
for /f "tokens=*" %%1 in ('dir /a-d /b E:\Archiwum\*.png') do (
set filename=%%1&set dirname=!filename:~0,4!\!filename:~0,9!
if not exist E:\Archiwum\!dirname! (md E:\Archiwum\!dirname!)
move %%1 E:\Archiwum\!dirname!\
)
Here's a quick rewrite of your script
#Echo Off
If Exist "E:\Archiwum\*.png" (CD /D "E:\Archiwum") Else Exit /B
SetLocal EnableDelayedExpansion
ClS
For %%A In (*.png) Do (Echo Processing %%A
Set "filename=%%~nA"
Set "dirname=!filename:~,4!\!filename:~,9!"
If Not Exist "!dirname!\" MD "!dirname!"
If Exist "!dirname!\%%A" (Echo Name conflict %%A already exists.
) Else Move "%%A" "!dirname!" > Nul)
You need to be careful of spaces in your file names in order to prevent having directory names with trailing spaces as well as the other things I mentioned in my comments.
Thanks for your feedback. I made two modifications to your solution and now it works just fine.
#Echo Off
If Exist "C:\Archiwum\*.png" (CD /D "C:\Archiwum") Else Exit /B
SetLocal EnableDelayedExpansion
ClS
#Echo Processing...
#Echo Off
For %%A In (*.png) Do (
Set "filename=%%~nA"
Set "dirname=!filename:~,4!\!filename:~,9!"
If Not Exist "!dirname!\" MD "!dirname!"
If Exist "!dirname!\%%A" (Echo Name conflict %%A already exists.
) Else Move "%%A" "!dirname!" > Nul)
I added second #Echo Off - without it commands from for loop where still shown in command window.
I moved #Echo Processing as I wanted it to be shown only once with all of the operations done in the background.
Thank you a lot for your help.
I have a bunch of files say,
xxx111.txt
xxx112.txt
xxx113.txt
I want to remove the last 3 characters of all the file names and I'm using this script
#echo off
setlocal enabledelayedexpansion
set X=3
for %%f in (*) do if %%f neq %~nx0 (
set "filename=%%~nf"
set "filename=!filename:~,-%X%!"
ren "%%f" "!filename!%%~xf"
)
popd
pause
This runs perfectly when the output filenames are different. However, in the above case all file will be output as xxx.txt and the script throws me the error
"A duplicate file name exists, or the file cannot be found".
Is there any way to tweak this so that duplicate files will be renamed and maybe numbered 1,2,3...?
Unfortunately I cannot install any other software.
#echo off
setlocal EnableDelayedExpansion
set X=3
for /F "delims=" %%f in ('dir /A:-D /B') do if "%%f" neq "%~NX0" (
set "filename=%%~Nf"
set "filename=!filename:~,-%X%!"
if exist "!filename!%%~Xf" call :getNewName "%%~Xf"
ren "%%f" "!filename!%%~Xf"
)
popd
pause
goto :EOF
:getNewName ext
set i=0
:nextNum
set /A i+=1
if exist "%filename%%i%%~1" goto nextNum
set "filename=%filename%%i%"
exit /B
You should not use plain for %%f command when renaming files. Depending on where the new names are placed in the list of original names, they may be processed a second time by the for %%f. Always use for /F for renaming.
i want to make a batch file, This Batch file must look out, into a folder with the name "Draft" and for every sub-folder will be make a search for a .txt file "list.txt" and when finds this .txt file, Then will be execute a copy from the folder "Draft" to the folder "Ready". I have written a small script but i have some issues.
#echo off
:loop
for /d %%i in ('dir "C:\Users\ntosis\Desktop\Draft" /ad /o:d /s /b') do (
SET a=%%i
echo %a%
)
echo Folder is empty or does not exist
timeout /t 15
goto loop
The problem in this small part of the script is that, the variable "a" cannot save the name of the folder, if i change the echo %a% to echo Hello World then the script prints only one time the message and not as long as the loop runs.
Any ideas?
I'm not sure if there are more bugs in the code but one problem is the missing of delayed expansion. Here is the fix:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:loop
for /f %%i in ('dir "C:\Users\ntosis\Desktop\Draft" /ad /o:d /s /b') do (
SET a=%%i
echo !a!
)
echo Folder is empty or does not exist
timeout /t 15
goto loop
You have to add SETLOCAL ENABLEDELAYEDEXPANSION at the beginning of your script and replace %a% with !a!. You always to do this when changing a variable inside a for loop (and also in many other cases). For an explanation check http://ss64.com/nt/delayedexpansion.html
EDIT: replaced for /d ... with for /f ...
After successfully removing a bunch of Google Drive Folder duplicates, some files retain a "filename(2)"name.
Is there a way to batch rename every file so the parenthesis and the number inside the parenthesis is gone?
That includes folders and sub-folders.
Try like this :
Create a file test.bat with the code below in it and replace the path to test in the var $path
#echo off
set $path="C:\Users\CN Micros\Desktop\PROGRAMMATION\test"
for /f "tokens=1-3 delims=^(^)" %%a in ('dir /b/a-d %$path%') do (
if exist %$path%\"%%a(%%b)%%c" echo ren %$path%\"%%a(%%b)%%c" "%%a%%c"
)
pause
Then run it in the CMD or by double clicking.
If the output is ok for you remove the echo
The program create 3 tokens : %%a = what's before the (), %%b What's inside the () and %%c what's after the ().
Then we arrange this 3 tokens to rename the files without the ().
If you have some file who have the same final name ie : "file(1)name", "file(2)name" --> "filename"
It will work only with the first one. If you have this case you have to add a counter at the end of file to be sure that they will be renamed.
This will create renfiles.bat.txt for you to examine in Notepad and then rename to .bat and execute if you are happy with it.
#echo off
dir /b /a-d *(*).* |find /i /v "%~nx0" |find /i /v "repl.bat" |repl "(.*)\(.*\)(\..*)" "ren \q$&\q \q$1$2\q" xa >"renfiles.bat.txt"
This uses a helper batch file called repl.bat - download from: https://www.dropbox.com/s/qidqwztmetbvklt/repl.bat
Place repl.bat in the same folder as the batch file or in a folder that is on the path.
Edit: This version will recurse through subdirectories:
#echo off
dir /b /s /a-d *(*).* |find /i /v "%~nx0" |find /i /v "repl.bat" |repl ".*\\(.*)\(.*\)(\..*)" "ren \q$&\q \q$1$2\q" xa >"renfiles.bat.txt"
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /f "delims=" %%a IN (
'dir /b /s /a-d "%sourcedir%\*" '
) DO (
SET "name=%%~na"
SETLOCAL ENABLEDELAYEDEXPANSION
SET "newname=!name:)=!"
SET "newname=!newname:(=!"
IF "!name!" neq "!newname!" (
IF EXIST "%%~dpa!newname!%%~xa" (ECHO cannot RENAME %%a
) ELSE (ECHO(REN "%%a" "!newname!%%~xa")
)
endlocal
)
GOTO :EOF
You'd need to set your required directory into sourcedir. I used u:\sourcedir which suits my testing.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
i want to create a dos script (.bat) to search on all sub folders and whenever it finds a file with the word MK11 in the file name it must create a folder named archive and move the file in it.
example:
c:\folder1\folder2\folderX\fileMK11.txt -> c:\folder1\folder2\folderX\archive\fileMK11.txt
c:\folder1\folder3\fMK11ile.txt -> c:\folder1\folder3\archive\fMK11ile.txt
I tried to make the following script from examples i have seen but the problem is that it creates the folder "archive" in the directory where the script is instead of the directory where the file is found.
setlocal ENABLEDELAYEDEXPANSION
set /a c=0
FOR /R %%i in (*MK11*) do (
set /a c=c+1
md archive
move "%%i" archive
)
endlocal
I think this script will get you down the road. I echoed a COPY command rather than a MOVE command, but some of the hard part is done.
#echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET TEMPFILE=%TEMP%\afinder_%RANDOM%_%RANDOM.tmp
DIR /S /B /A-D *MK11* >%TEMPFILE%
FOR /F "usebackq delims=" %%f IN (`type %TEMPFILE%`) DO (
ECHO "%%f"
FOR /F "delims=\ tokens=*" %%a IN ("%%f") DO (
SET PNAME="%%~pa"
ECHO PNAME is set to !PNAME!
ECHO "!PNAME:~-9,7!"
REM Check to see if this file is already in an Archive directory.
IF "!PNAME:~-9,7!" == "Archive" (
echo got one
) else (
echo not one
IF NOT EXIST "!PNAME!\Archive" (MKDIR "!PNAME!\Archive")
echo COPY %%f "!PNAME!\Archive"
)
)
)
IF EXIST "%TEMPFILE%" (DEL "%TEMPFILE%")
EXIT /B 0