Batch - For - Rename Files in several subfolders with count - batch-file

We have many Oracle-Database-Client versions in our company.
The tnsnames.ora will be changed often.
I like to create a package (batch) to backup (rename) the present file in all versions of Oracle Client (if there are two or more versions installed) and after that, copy the new file.
My script for now looks so:
setlocal enabledelayedexpansion
set /a count=0
set OracleDir="%SystemDrive%\oracle\product"
for /d %%i in (%OracleDir%\*) do (
set dir=%%i\client_1\network\admin\
PushD !dir:\\=\!\
for /f "tokens=*" %%a in ('dir /b /od tnsnames.ora') do (
rename "%%a" "tnsnames-%Date%-Backup-!count!.bak"
)
set /a count+=1
IF NOT EXIST "%%i\client_1\network\admin\tnsnames.ora" (
copy "%~dp0tnsnames.ora" "%%i\client_1\network\admin\" /Y
)
)
endlocal
So far so good. But the script will only create a backupfile once.
But it must create a new "tnsnames-%Date%-Backup-!count!.bak" everytime I run the script.
Hope you know what I mean?
I'm sure, i need a jump point somewhere but no idea where.

IMO you did overcomplicate things.
The inner for is useless doing a dir for a file at a fixed location. This is better checked with an if exist.
If you then rename that file the next if is also useless, it can't exist - you just renamed it (better check if the rename was succesful)
setlocal enabledelayedexpansion
set /a count=0
set OracleDir="%SystemDrive%\oracle\product"
for /d %%i in (%OracleDir%\*) do (
set "dir=%%i\client_1\network\admin\"
PushD "!dir:\\=\!\" || (Echo couldn't pushd "!dir:\\=\!\"&Pause)
Set "Stamp=!Date!.!Time:~,2!.!Time:~2,2!"
if exist tnsnames.ora if not exist "tnsnames-!Stamp!-Backup.bak" (
rename tnsnames.ora "tnsnames-!Stamp!-Backup-!count!.bak"
)
set /a count+=1
if not exist tnsnames.ora copy "%~dp0tnsnames.ora" "!dir!"
PopD
)
endlocal

Related

Batch File Loop Doesn't Include Nested Loop

Edit1:
So it seems my loop runs to the very last record and then executes the mkdir and MOVE commands. I feel like I'm missing parentheses somewhere?
FOR %%i IN (%folderPath%\*.Pdf) DO SET fileName=%%i
ECHO %fileName%
FOR /f "tokens=3-4 delims=_" %%a IN ("%fileName%") DO SET fileClientID=%%a_%%b
ECHO %fileClientID%
REM Check to see if folders exist, and if they do not, create them
IF NOT EXIST "%folderPath%\%fileYear%" mkdir %folderPath%\%fileYear%
IF NOT EXIST "%folderPath%\%fileYear%\%fileMonth%" mkdir %folderPath%\%fileYear%\%fileMonth%
IF NOT EXIST "%folderPath%\%fileYear%\%fileMonth%\%fileClientID%" mkdir %folderPath%\%fileYear%\%fileMonth%\%fileClientID%
REM Moves the file from source path to destination path
SET fileSourcePath="%fileName%"
SET fileDestPath="%folderPath%\%fileYear%\%fileMonth%\%fileClientID%"
MOVE "%fileSourcePath%" "%fileDestPath%"
PAUSE
So I finally finished the code and it all works as it should. I really appreciate everyone's help getting me to this point as this is my first batch file script I've ever written. Final product below and of course if there are any best practices or more efficient ways of writing it, I'd love the feedback. Thanks again!
#ECHO OFF
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
SET folderPath="C:\Users\nha\Desktop\FolderMover\Test"
FOR %%a IN (%folderPath%\*.Pdf) DO (
SET fileDate=%%~ta
SET fileName=%%a
FOR /f "tokens=1,3 delims=/, " %%a IN ("!fileDate!") DO (
SET fileYear=%%b
SET fileMonth=%%a
For /f "tokens=3-4 delims=_" %%a IN ("!fileName!") DO (
SET fileClientID=%%a_%%b
IF NOT EXIST !folderPath!\!fileYear!\!fileMonth!\!fileClientID! mkdir !folderPath!\!fileYear!\!fileMonth!\!fileClientID!
SET fileSourcePath=!fileName!
SET fileDestPath=!folderPath!\!fileYear!\!fileMonth!\!fileClientID!
MOVE !fileSourcePath! !fileDestPath!
)
)
)

Bat file to compare folders

I'm looking to create a bat file to compare local folders from a dir command with folders on a server, and then delete the local folders if they do not exist on the server. Additionally, it is having issues with directories including spaces, but I have not looked into this yet.
My current code is not working correctly. Could anyone provide some guidance please?
Code:
REM Search local directories for files, delete if not present on server
set n=0
set count=0
for /f %%a in ('dir /a:d /b %_Entry_Local_Status60_path%') do (
set folder[!n!]=%%a
set /A a+=1
set /A n+=1
set /A count+=1
)
set n=0
for /L %%a in (0,1,%count%) do (
echo !folder[%n%]!
if not exist %_Entry_Network_Status60_path%\!folder[%n%]! rmdir %_Entry_Local_Status60_path%\!folder[%n%]!
set /A n+=1
)
I use the following to compare files within different folders and delete the ones from first folder which does not exists on second one. With some adaptation probably you could use something similar with folders and not files. This is based on FC and you have to provide the two absolute paths:
echo off
set "Folder1=path\to\Folder1"
set "Folder2=path\to\Folder2"
for /f "delims=" %%F in ('dir /b "%folder2%"') do (
if not exist "%folder1%\%%F" (
fc /b "%folder1%\%%F" "%folder2%\%%F"
if "%errorlevel%" EQU "1" (
del "%folder1%\%%F" && echo Deleted "%%F"
)
) else (
del "%folder1%\%%F" && echo Deleted "%%F"
)
)
pause
Exit
You should take a look at the robocopy command. I think robocopy _source_ _target_ /purge does exactly what you want.

Batch - Why archive is not being renamed?

So, as we all know, when we use batch file to move archive to folder, where another archive with the same name exists, batch script will just replace old Archive.
Since I am making Archivating system, this is really bad, because important data may be lost in a proccess of archiving, hence, I made ticket in SO, to get information on how to fix this issue. Here is my test code:
set year=%DATE:~6,4%
if not exist "V:\01_%YEAR%" mkdir "V:\01_%YEAR%" - Creates folder 01_2016
for /d %%X in (01_%YEAR%) do "C:\Program Files\7-Zip\7z.exe" a "%%X.7z" "%%X\" - Archivates folder
MOVE "V:\01_%YEAR%.7z" "Z:\" - moves Archive.
User named elzooilogico, suggested, instead of Move command, to use this:
set "last=0"
set "filename=Z:\01_%YEAR%.7z"
if exist "Z:\01_%YEAR%.7z" (
for /R %%i in ("Z:\01_%YEAR%(*).7z") do (
for /F "tokens=2 delims=(^)" %%a in ("%%i") do set "last=%%a"
)
set/a last+=1
set "filename=Z:\01_%YEAR%(%last%).7z"
)
MOVE "V:\01_%YEAR%.7z" "%filename%"
Unfortunetely I still did not understand, why did code not work, so I remade it a bit, and here is what I came up with.
set YEAR=%DATE:~6,4%
set filename=C:\Users\PP_lemev\Desktop\New folder\01_%YEAR%.7z
cd /d C:\Users\PP_lemev\Desktop\New folder
if not exist "C:\Users\PP_lemev\Desktop\New folder\01_%YEAR%" mkdir "C:\Users\PP_lemev\Desktop\New folder\01_%YEAR%"
for /d %%X in (01_%YEAR%) do "C:\Program Files\7-Zip\7z.exe" a "%%X.7z" "%%X\"
if exist "C:\Users\PP_lemev\Desktop\New folder\vairis\01_%YEAR%.7z" (
for /R %%i in ("C:\Users\PP_lemev\Desktop\New folder\01_%YEAR%(*).7z") do (
for /F "tokens=2 delims=(^)" %%a in ("%%i") do set "last=%%a"
)
set/a last+=1
set "C:\Users\PP_lemev\Desktop\New folder\01_%YEAR%(%last%).7z"
)
MOVE "%filename%" "C:\Users\PP_lemev\Desktop\New folder\vairis"
Could someone please explain to me, why is Archive name not being renamed after script checks, if Archive already exists?
Regards, Vairis
OK, new approach
#echo off
SetLocal EnableDelayedExpansion
set/a last=1
set "YEAR=%DATE:~6,4%"
set "myFolder=C:\Users\PP_lemev\Desktop\New folder\vairis"
set "filename=%myFolder%\01_%YEAR%.7z"
if exist "%myFolder%\01_%YEAR%.7z" (
for /R %%i in ("%myFolder%\01_%YEAR%(*).7z") do set/a last+=1
set "last=000!last!"
set "filename=%myFolder%\01_%YEAR%(!last:~-4!).7z"
)
for /d %%X in (01_%YEAR%) do "C:\Program Files\7-Zip\7z.exe" a "%filename%" "%%X\"
endlocal

Windows batch script to copy newest files with partial names

I have a backup program that saves .bak files into a folder which it rotates on a weekly basis automatically.
The files are given given names like this:
DB_Live_19052015.bak
DB_Test_19052015.bak
DB_Live_18052015.bak
DB_Test_18052015.bak
The backup program doesn't allow me to edit these names and I actually don't want it to.
What I do need is to be able to copy the newest file of each set DB_Live_XXXXXXXX.bak & DB_Test_XXXXXXXX.bak and rename them to drop the date so I end up with files like this for DR:
dr/DB_Live.bak
dr/DB_Test.bak
This would be overwritten each time the script was run.
No I can copy the latest file in a folder and rename it using scripting but I cannot get my head round how to
A. get the set of latest files (multiple)
B. rename these files based on their original names to drop only the on the end.
What I am expecting to have to do is the following:
copy the latest files to a dr folder
get the file names for each file
rename the files and overwrite anything already there with that name
I'm going to be adding this scripting into the backup program so it runs when the backup has finished.
The reason for these files is so I can RSYNC them off site without sending the whole file every time.
#echo off
setlocal enableextensions disabledelayedexpansion
set "source=%cd%\source"
set "target=%cd%\target"
for %%a in (DB_Live DB_Test) do (
set "first=1"
for /f "delims=" %%b in ('
dir /a-d /tw /o-d /b "%source%\%%a_*.bak"
') do if defined first (
set "first="
copy /b /y "%source%\%%~b" "%target%\%%a%%~xb"
)
)
For each set of files, execute a dir command in reverse modified date order. In this list the first file is the last modified. Copy this file to the target overwritting the existing file (if present).
#echo off
echo.>%temp%\tempone.txt
if not exist dr md dr
if not exist dblive md dblive
if not exist dbtest md dbtest
setlocal enabledelayedexpansion
for %%I in (*) do (
set red=%%I
set blue=!red:~0,7!
if "!blue!"=="DB_Live" copy /y !red! dblive>nul
if "!blue!"=="DB_Test" copy /y !red! dbtest>nul
)
pushd %cd%
cd dblive
for %%I in (*) do (
set green=%%I
set green=!green:DB_Live_=!
set green=!green:.bak=!
echo !green! >>%temp%\tempone.txt
)
set max=0
for /f %%x in (%temp%\tempone.txt) do (
set "FN=%%~nx"
if !FN! GTR !max! set max=!FN!
)
echo the latest dblive file is DB_Live_!max!.bak--copied to dr folder
set dblatest=DB_Live_!max!.bak
copy /y !dblatest! %temp%>nul
popd
copy /y %temp%\!dblatest! dr>nul
::same for dbtest
pushd %cd%
cd dbtest
for %%I in (*) do (
set green=%%I
set green=!green:DB_Test_=!
set green=!green:.bak=!
echo !green! >>%temp%\temptwo.txt
)
set max=0
for /f %%x in (%temp%\temptwo.txt) do (
set "FN=%%~nx"
if !FN! GTR !max! set max=!FN!
)
echo the latest dbtest file is DB_Test_!max!.bak--copied to dr folder
set dblatest=DB_Test_!max!.bak
copy /y !dblatest! %temp%>nul
popd
copy /y %temp%\!dblatest! dr>nul
::rename both files
pushd %cd%
cd dr
ren DB_Live_* DB_Live.bak
if %errorlevel%==0 echo renamed dblive
ren DB_Test_* DB_Test.bak
if %errorlevel%==0 echo renamed dbtest
pause
put in the same folder as the .bak files. hope this helps!

Batch script - concatenate sequential numbers on files to keep the names unique

I'm working on a script for copying files in a folder which corresponds to the file's name and I have that part worked out using a FOR loop which checks to make sure the destination folder exists and copies the files once it has verified that it does. Example: 11-01111_ABC_DEF.pdf would go into /11/0111/. The length may vary by one or two characters but the format is consistent. I've copied my basic script below.
My problem is that sometimes a file with the same name needs to be processed. How could I go about concatenating a number to the end of the file if one or more copies of the file already exists in the destination folder?
setlocal enableextensions enabledelayedexpansion
for %%x in (*.PDF *.TXT) do (
set "source="C:\files"
set "dest=R:\"
set "filename=%%x"
set "prefix=!filename:~0,2!"
set "folder=!filename:~3,5!"
if not exist !dest!\!prefix!\!folder! MOVE !filename! !source!\failed
if exist !source!\!filename! MOVE !filename! !dest!\!prefix!\!folder!
)
setlocal ENABLEDELAYEDEXPANSION
set "dest=worked"
for %%i in (*.pdf *.txt) do (
for /f "tokens=1-3* delims=-_." %%j in ("%%i") do (
if exist "%dest%\%%j\%%k" if exist "%dest%\%%j\%%k\%%i" if exist "%dest%\%%j\%%k\%%j-%%k-1_%%l_%%m" (
for /f "tokens=1-9* delims=-_." %%n in ('dir %dest%\%%j\%%k\%%j-%%k*-* /b') do set /a inc=%%p
set /a inc+=1
move "%%i" "%dest%\%%j\%%k\%%j-%%k-!inc!_%%l_%%m" || move "%%~i" "failed"
set inc=
)
if exist "%dest%\%%j\%%k\%%i" if not exist "%dest%\%%j\%%k\%%j-%%k-1_%%l_%%m" (
move "%%i" "%dest%\%%j\%%k\%%j-%%k-1_%%l_%%m" || move "%%~i" "failed"
)
if exist "%dest%\%%j\%%k" if not exist "%dest%\%%j\%%k\%%~i" (
move "%%~i" "%dest%\%%j\%%k\%%~i" || move "%%~i" "failed"
)
if not exist "%dest%\%%j\%%k" move "%%~i" "failed"
)
)
put this in the folder with the .txts and .pdfs comment if you want me to change something.

Resources