Batch script file to copy and rename files - windows

I'm writing batch script which I'll use to copy files from location A to location B with rename of a source file from location A if the same file exists already in location B.
Currently Im using snippet from another topic here on stack but it doesnt work on files from subfolders, could anyone help me with code below so it work on all files and subdirectiories from both locations? Many thanks!
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET sourcedir="D:\TEST\FROM"
SET destdir="D:\TEST\TO"
SET /a count=0
for %%c in (%sourcedir%\*.*) do (
CALL :select
ECHO copy "%%c" "%destdir%\%%~nc_!count!%%~xc" /s
)
GOTO :EOF
:select
SET /a count+=1
IF EXIST "%destdir%\%%c" GOTO select
GOTO :eof

Replace your for loop with the following for loop:
for /R "%sourcedir%" %%c in (*.*) do (what you like)
Also, why do you want the following piece of code?
copy "%%c" "%destdir%\%%~nc_!count!%%~xc" /s
Just copy "%%c" %destdir%
More generally you can write:
#ECHO OFF
SET sourcedir="D:\TEST\FROM"
SET destdir="D:\TEST\TO"
:: SET /a count=0
for /R "%sourcedir%" %%c in (*.*) do (
:: SET /a count+=1
IF NOT EXIST "%destdir%\%%c" (
echo copy "%%c" %destdir%
)
)
Hope you are fine with this, possible dublicate of Windows batch file with loop through subfolders

Sharing with what I managed to get so far, works for what I needed, however still not doing well for subfolders:
#ECHO OFF
SET "sourcedir= "
SET "destdir= "
SET "HH=%TIME:~0,2%"
SET "MM=%TIME:~3,2%"
SET "SS=%TIME:~6,2%"
SET "_Time=%HH%%MM%%SS%"
FOR /R "%sourcedir%" %%G IN (*.*) DO (
IF EXIST "%destdir%\%%~nG%%~xG" (
COPY /V /Z "%%G" "%destdir%\%%~nG_duplicate_%_Time%%%~xG"
) ELSE (
COPY /V /Z "%%G" "%destdir%\%%~nG%%~xG")
)

Related

Loop that appends filename when copying same filename from different folders to a new folder

I have the following code to search for a specific file name (ratings.zil) across multiple folders and copy them to a new folder:
for /R %f in (ratings.zil) do #IF EXIST %f copy "%f" "C:\here"
But when the file copies to the new folder it overwrites instead of appending a number at the end of each ratings.zil – i.e. ratings(1).zil, ratings(2).zil. Is there a way to add a loop to the above code that will append a number after each file?
This question was originally marked as a duplicate, except the answer for the duplicate only works when you’re copying a file within the same folder.
Here is a slightly ammended version of DBenhams answer.
#echo off
setlocal disableDelayedExpansion
if "%~2" equ "" echo Error: Insufficient arguments>&2&exit /b 1
set "source=%~f1"
set "target=%~f2"
md "%target%"
set /a cnt=0
for /r "%source%" %%F in (ratings.zil) do if "%%~dpF" neq "%target%\" (
if exist "%%F" (
if exist "%target%\%%~nxF" (
set /a cnt+=1
set "full=%%F"
set "name=%%~nF"
set "ext=%%~xF"
setlocal enableDelayedExpansion
copy "!full!" "!target!\!name!(!cnt!)!ext!" >nul
endlocal
) else copy "%%F" "%target%" >nul
)
)
In order to run this, you need to save the file as something like myRename.cmd then simply open cmd.exe and run it as:
myRename.cmd "C:\Source of files" "D:\Destination"
If you perfer to place this in a set directory and have a static destination folder and be able to just double click it, then this will do:
#echo off
setlocal disableDelayedExpansion
set "target=C:\here"
md "%target%"
set /a cnt=0
for /r %%F in (ratings.zil) do if "%%~dpF" neq "%target%\" (
if exist "%%F" (
if exist "%target%\%%~nxF" (
set /a cnt+=1
set "full=%%F"
set "name=%%~nF"
set "ext=%%~xF"
setlocal enableDelayedExpansion
copy "!full!" "!target!\!name!(!cnt!)!ext!" >nul
endlocal
) else copy "%%F" "%target%" >nul
)
)

How to generate automatic numbering of output files in a batch file?

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.

Windows cmd sort files by file type and store them in folder

I would like to have a batch file wich will sort files by file type and sorts them into folder.
For example I will run this batch file in some folder and .PDF files will be saved in "PDF" folder, same to do with other file types. Is possible to do that in command line?
Thank you.
Please put the code below in a .bat file and save it to your folder with files and run it.
#echo off
rem For each file in your folder
for %%a in (".\*") do (
rem check if the file has an extension and if it is not our script
if "%%~xa" NEQ "" if "%%~dpnxa" NEQ "%~dpnx0" (
rem check if extension forlder exists, if not it is created
if not exist "%%~xa" mkdir "%%~xa"
rem Copy (or change to move) the file to directory
copy "%%a" "%%~dpa%%~xa\"
)
)
Try this:
#echo off
setlocal enabledelayedexpansion
for %%a in (*.*) do (
set "fol=%%~xa" & set "fol=!fol:.=!"
if not exist !fol! md !fol!
for /f %%b in ('dir /on /b *.*') do (
if %%~xb EQU .!fol! move %%~nxb !fol!
)
)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET destdir=c:\destdir
SET "extdone=:"
FOR /f "delims=" %%a IN ('dir /b /a-d') DO (
SET ext=%%~xa
IF DEFINED ext (
SET extdone|FIND /i ":%%~xa:" >NUL
IF ERRORLEVEL 1 (
SET extdone=:%%~xa: !extdone!
IF EXIST "%destdir%\!ext:~1!" (
ECHO MOVE "*%%~xa" "%destdir%\!ext:~1!"
) ELSE (ECHO no MOVE "%%~xa")
)
)
)
GOTO :EOF
This batch should do as you ask.
The required commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MOVE to MOVE to actually move the files.
I've assumed that you only wish to move the files if destinationdirectory\extensionfound exists. If you want to create a directory for a new extension, simply add a line
md "%destdir%\!ext:~1!" 2>nul
after the SET extdone=:%%~xa: !extdone! line.

Write batch file to count folders inside main folder

I am new to this, i am trying to write a batch file to calculate number of folders inside folder. Can someone please help me?
Here is folder system:
I have hundreds of folders like:
Area1
Area2
Area3
....
Inside each of above folder there is one folder named "Zone".
What i am trying to find is number of folders inside Zone folder for each Area1, Area2... so on.
start one folder above the AREAx folders:
#echo off &setlocal
for /d %%i in (*.*) do (
pushd %%i\ZONE
set /a count=0
for /d %%j in (*.*) do set /a count+=1
popd
call echo %%count%% folder(s^) in %%i\ZONE
)
endlocal
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /f %%i IN ('dir /b/ad area*') DO (
IF EXIST ".\%%i\zone\." (
FOR /f %%c IN (' DIR /ad ".\%%i\zone\"') DO SET /a count=%%c-2 2>nul
ECHO ".\%%i\zone" : !count! directories
) ELSE (ECHO ".\%%i\zone" does NOT EXIST
)
)

Using batch script to automatically copy latest file to folder

I would like to call for help on my attempt to create a script which will automatically check last modified file and transfer it to destination.
What I have is this:
#Echo Off
Set _Delay=1
for /f "tokens=1,2,3 delims==" %%a in (config.ini) do (
if %%a==source set _Monitor=%%b
if %%a==destination set _Dest=%%b
if %%a==timer set _Timer=%%b
)
Set _Base=%temp%\BaselineState.dir
Set _Chck=%temp%\ChkState.dir
Set _OS=6
Ver|Findstr /I /C:"Version 5">Nul
If %Errorlevel%==0 Set _OS=5 & Set /A _Delay=_Delay*1000
Goto :_Xfer
:_StartMon
#echo off
SET R1=Start /w Sync1.vbs
Call :_SetBaseline "%_Base%" "%_Monitor%"
:_MonLoop
If %_OS%==5 (Ping 1.0.0.0 -n 1 -w %_Delay%>Nul) Else Timeout %_Delay%>Nul
Call :_SetBaseline "%_Chck%" "%_Monitor%"
FC /A /L "%_Base%" "%_Chck%">Nul
If %ErrorLevel%==0 Goto _MonLoop
::
for /l %%a in (%_Timer%,-1,0) do (
#Echo::::::::::::::::::::::::::::::::::::::::::::::
#Echo:: SEC Auto Transfer ::
#Echo:: Aizal 16 June 2012 ::
#Echo::::::::::::::::::::::::::::::::::::::::::::::
#Echo This script will scan SEC Data Folder for
#Echo new files every 30 minutes and will copy
#Echo it to the Server. Make sure you set correct
#Echo folder before using this script.
ECHO.
ECHO Currently recording:
FOR /F %%a in ('xcopy "%_Monitor%\*.SEC" "%_Dest%" /L /Y') DO (
IF NOT EXIST "%_Dest%.\%%~nxa" ECHO %%~nxa
)
ECHO Refreshing...
ECHO Please wait %%a seconds...
%R1%
cls
)
::
:_Xfer
FOR /F %%a in ('xcopy "%_Monitor%\*.SEC" "%_Dest%" /L /Y') DO (
IF NOT EXIST "%_Dest%.\%%~nxa" xcopy "%%a" "%_Dest%" /Y
)
::
Echo.Change Detected
ECHO.
Goto :_StartMon
:::::::::::::::::::::::::::::::::::::::::::::::::::
:: Subroutine
:::::::::::::::::::::::::::::::::::::::::::::::::::
:_SetBaseline
If Exist "%temp%\tempfmstate.dir" Del "%temp%\tempfmstate.dir"
For /F "Tokens=* Delims=" %%I In ('Dir /S "%~2"') Do (
Set _Last=%%I
>>"%temp%\tempfmstate.dir" Echo.%%I
)
>"%~1" Findstr /V /C:"%_Last%" "%temp%\tempfmstate.dir"
Goto :EOF
Now, if you noticed the script will compare the content of source folder with the content of the destination folder and will copy the files from source if there is not already file in destination. I would like to know if someone can help me figuring out how to make the script to check the last modified file in source folder and ONLY copy it to the destination AND if the said file is currently in use/being write to then script will wait until it finished before trying to copy it again.
Also, right now I have to edit source.ini file to specify which folder I want to monitor and each time I have to change the subfolder path to watch for changes, is there a way to watch parent folder for any new files and take that file to the destination?
I found this script on the net but hoping to check the file not based on day but instead of time.
::Copy Files Made Or Modified Today
#echo off
setlocal
set source= <source directory>
set dest= <destination directory>
pushd "%source%"
set t=%date:~4%
::for /f %%a in ('dir /b /a-d /o-d') do call :PROCESS "%%a"
goto :eof
popd
:PROCESS
for /f %%j in ('echo %~t1') do set d=%%j
if "%d%"=="%t%" copy %1 "%dest%"
goto :eof
Hope to find the solution from here.
Many thanks
With this you'll get the last modified file:
for /f %%A in ('dir /b /tw /o-d not-mandatory-file-mask') do (
set last_file=%%A
goto :endloop
)
:endloop
With this you'll copy the file if it is possible. If not it will try again and again:
:tryagain
set /a errorlevel=0
copy some_dir\%last_file% %destination%
if %errorlevel% NEQ 0 (
sleep 10
goto :tryagain
) else (
goto :end
)
:end

Resources