Loop through SET variable and perform task - batch-file

I am trying to figure out how to loop through a list of SET variables and perform a simple script. This is run in batch mode. Any tips on how to adapt the following code so that it loops through the SET dir variable list?
SET YYYY=%date:~10,4%
ECHO Its %YYYY%
SET dir=dir1, dir2, dir3, dir4,...dirN
ECHO %dir%
:: Loop through each SET dir and perform the following.
:: Create a current year dir in remote directory
C:
cd "C:\my\dir\here\%dir%"
if not exist %YYYY% mkdir %YYYY%
:: Copy files from local to remote for each sub directory
E:
cd "E:\FTP\localdrive\%dir%"
XCOPY "E:\FTP\localdrive\%dir%" "C:\my\dir\here\%dir%\%YYYY%" /S /Y
After valuable comments from users, this appears to work but fails to make dirs 2 through 4.
SET YYYY=%date:~10,4%
ECHO Its %YYYY%
SET dir=dir1, dir2, dir3, dir4
FOR /F "tokens=1 delims=," %%a in (%dir%) do (
if not exist %dir md E:\my\dir\here\%dir%
)
Revised to below and still fails - "%%a was unexpected at this time" on what I think was the md E:\my\dir\here\%%a
SET YYYY=%date:~10,4%
ECHO Its %YYYY%
SET dir=dir1, dir2, dir3, dir4
FOR /F "tokens=1 delims=," %%a in (%dir%) do (
md E:\my\dir\here\%%a
)

Just for information, an alternative to the FOR loop method:
#Echo Off
(Set _yyyy=%DATE:~10,4%)
Echo= It's %_yyyy%
(Set _fold=dir1 dir2 dir3 dir4)
Echo= %_fold%
:: Loop through each Set _fold.
Call :Loop %_fold%
Pause
Exit/B
:Loop
:: Copy files from local to remote for each sub directory
If Not Exist "C:\my\dir\here\%1\%_yyyy%\" MD "C:\my\dir\here\%1\%_yyyy%"
RoboCopy "E:\FTP\localdrive\%1" "C:\my\dir\here\%1\%_yyyy%" /S
Shift
If '%1 Equ ' GoTo :EOF
GoTo :Loop

SET dir=dir1, dir2, dir3, dir4,...dirN
for %%a in (%dir%) do (
echo doing my stuff for %%a
)

Related

batch to display folders to select from, user selects folder, then it copies that folder to another folder

So what I'm trying to do is, i have a bat file that makes timestamped backups(for example, 180126_053327 in the format: yymmdd_hhmmss). I'm trying to create this bat to add to it, so i can have it lookup those backups, display in console to allow the user to select the backup they want to restore by inputting the number they want and then copy it to a location.
so far what i have creates this:
Pic of what I have so far
The pic above is from the following script:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
set i=0
For /f %%a in ('dir I:\AM_Configs-backups\ /B /A /D') do (
set /a i+=1
echo !i! %%a
set dir!i!=%%a
)
echo.
set /p uin="Select a directory [1-!i!]: "
set udir=!dir%uin%!
echo Selected - %udir%
md c:\test2
copy %udir% c:\test2
#PAUSE
I keep getting this:
Select a directory [1-29]: 27
Selected - 180126_053327
The system cannot find the file specified.
Press any key to continue . . .
I got the script above from this link: Prompting user to select directory in batch file
It cannot be found because %udir% is not in the current directory. This means that your base directory, I:\AM_Configs-backups, needs to be pre-fixed to your Copy command.
Copy "I:\AM_Configs-backups\%udir%" "C:\test2"
Also here is an alternative to the linked example you provided in your question:
#Echo Off
SetLocal EnableDelayedExpansion
Set "baseDir=I:\AM_Configs-backups"
For /F "Delims==" %%A In ('"(Set dir[) 2>Nul"') Do Set "%%A="
Set "i=0"
For /D %%A In ("%baseDir%\*") Do (Set /A i+=1 & Set "dir[!i!]=%%~nxA")
If %i% Equ 1 (Set "dir[X]=%baseDir%\%dir[1]%") Else Call :Menu
Rem Your commands using the selected directory begin below
Echo you selected %dir[X]%
If Not Exist "C:\test2\" MD "C:\test2"
Copy "%dir[X]%" "C:\test2"
Pause
Exit /B
:Menu
For /L %%A In (1,1,%i%) Do (Echo %%A. !dir[%%A]!)
Set /P "dir[X]=Select a directory from the above list: "
If Not Defined dir[%dir[X]%] (ClS & GoTo Menu)
Set "dir[X]=%baseDir%\!dir[%dir[X]%]!"
You can adjust your base directory on line 3 and put your own commands from line 9 onwards, (up to the Exit /B).
You should consider using RoboCopy for copying directories!
Edit
For the XCopy version, you'd probably need to change to:
#Echo Off
SetLocal EnableDelayedExpansion
Set "baseDir=I:\AM_Configs-backups"
For /F "Delims==" %%A In ('"(Set dir[) 2>Nul"') Do Set "%%A="
Set "i=0"
For /D %%A In ("%baseDir%\*") Do (Set /A i+=1 & Set "dir[!i!]=%%~nxA")
If %i% Equ 1 (Set "dir[X]=%dir[1]%") Else Call :Menu
Rem Your commands using the selected directory begin below
Echo you selected %dir[X]%
XCopy "%baseDir%\%dir[X]%" "%AppData%\Awesomeminer\%dir[X]%" /S /I /F /Y 2>Nul
Echo Starting Awesome Miner...
Start "" "%ProgramFiles(x86)%\Awesome Miner\AwesomeMiner.exe"
Pause
Call "Switch-N-Bkup.bat"
Pause
Exit /B
:Menu
For /L %%A In (1,1,%i%) Do (Echo %%A. !dir[%%A]!)
Set /P "dir[X]=Select a directory from the above list: "
If Not Defined dir[%dir[X]%] (ClS & GoTo Menu)
Set "dir[X]=!dir[%dir[X]%]!"
For the RoboCopy version you'd change line 11 to:
RoboCopy "%baseDir%\%dir[X]%" "C:\test2\%dir[X]%" /S 2>Nul
...plus any additional switches you may need
I ended up using this cus i have another batch for switching and backing up:
to kinda give you an idea, i have a primary bat for switching and copying configs, which will start teh program automatically after their copied. in that bat i also have code for backing up current configs to a location using time/date and creates the folders in this format: yymmdd_hhmmss...i needed an easy restore function, which with the link and code you provided helped with the user able to select which folder to restore and copying it to the programs data folder to be used, then auto-starting the program using the copied config.
#Echo Off
SetLocal EnableDelayedExpansion
Set "baseDir=I:\AM_Configs-backups"
For /F "Delims==" %%A In ('"(Set dir[) 2>Nul"') Do Set "%%A="
Set "i=0"
For /D %%A In ("%baseDir%\*") Do (Set /A i+=1 & Set "dir[!i!]=%%~nxA")
If %i% Equ 1 (Set "dir[X]=%baseDir%\%dir[1]%") Else Call :Menu
Rem Your commands using the selected directory begin below
Echo you selected %dir[X]%
REM If Not Exist "C:\test2\" MD "C:\test2"
xcopy "%dir[X]%" "%USERPROFILE%\AppData\Roaming\Awesomeminer\" /S /F /R /Y
START C:\"Program Files (x86)"\"Awesome Miner"\AwesomeMiner.exe
ECHO Starting Awesome Miner...
#Pause
CALL Switch-N-Bkup.bat
exit /b
:Menu
For /L %%A In (1,1,%i%) Do (Echo %%A. !dir[%%A]!)
Set /P "dir[X]=Select a directory from the above list: "
If Not Defined dir[%dir[X]%] (ClS & GoTo Menu)
Set "dir[X]=%baseDir%\!dir[%dir[X]%]!"

Create a folder using substring of filename

I want to fetch two sub string from my file name in order to create Folder String.
My file name is "SM-SM-ABC_ab12 cd34_AA 11_abc123.txt"
here "ab12 cd34" is 1st folder and "AA 11" is 2nd folder
I have written a code but After adding #Compo code I ma not able to move file to directory. I want to move multiple files to respective folders.
Can some one help whats wrong?
#Echo Off
set Path1= d:\A
:: SDate=DAYMONTHYEAR FORMAT of Systemdate
echo %Path1%
set SDate=%date:~7,2%%date:~4,2%%date:~10,4%
echo %SDate%
::Variable for folder path
Pushd %Path1%
for %%i in (*.*) do SET "FPath=%%~ni"
For /F "Tokens=2-3 Delims=_" %%A In ("%FPath%") Do (
Set "FoldOne=%%A"
Set "FoldTwo=%%B"
if not exist "%Path1%\%FoldOne%\%FoldOne%\%SDate%" (
mkdir "%Path1%\%FoldOne%\%FoldOne%\%SDate%" )
move %Path1%\* "%Path1%\%FoldOne%\%FoldTwo%\%SDate%\"
echo test %Path1%
echo test %FPath%
)
GoTo :EOF
Is this what you are trying to achieve?
#Echo Off
Set "FPath=SM-SM-ABC_ab12cd34_AA11_abc123.txt"
For /F "Tokens=2-3 Delims=_" %%A In ("%FPath%") Do (
Set "FoldOne=%%A"
Set "FoldTwo=%%B")
Echo(%%FoldOne%%=%FoldOne%
Echo(%%FoldTwo%%=%FoldTwo%
Timeout -1
GoTo :EOF
[Edit /]The following code may provide you with a solution for your updated requirements:
#Echo Off
Set "Path1=D:\A"
If /I Not "%CD%"=="%Path1%" Pushd "%Path1%" 2>Nul || Exit/B
For /F "EOL=L" %%A In ('WMIC OS GET LocalDateTime') Do For %%B In (%%~nA
) Do Set "SDate=%%B"
Set "SDate=%SDate:~6,2%%SDate:~4,2%%SDate:~,4%"
For %%A In ("*_*_*_*.*") Do Call :Sub "%%A"
Timeout -1
GoTo :EOF
:Sub
For /F "Tokens=2-3 Delims=_" %%A In (%1) Do If Not "%%A"=="" If Not "%%B"=="" (
If Not Exist "%%A\%%B\%SDate%\" MD "%%A\%%B\%SDate%"
Move %1 "%%A\%%B\%SDate%")

Check for new folder after running bat commands

Is there a way to check if a new folder (exact name is unknown) has been created inside a specific parent folder as a result of running previous commands in bat file? If yes - run one more command with the full path to a new folder as an argument to that command.
Right now I am using a folder monitoring software to run another bat if new folder is created. I would like to have just one script performing both tasks.
Thank you for your help.
change the root_folder location on the second line
#echo off
set "root_folder=C:\something"
setlocal enableDelayedExpansion
set counter=1
for /d /r "%root_folder%" %%a in (*) do (
set "dirs[!counter!]=%%~sa" >nul
set /a counter=counter+1
)
rem ############################
rem # call your code here !!! #
rem ############################
call commands.bat
rem for /l %%l in (1,1,!counter!) do (
rem dir /x /b /s /a:d "%root_folder%" | findstr /i "dirs[%%l]"
rem )
set flag=0
for /d /r "%root_folder%" %%a in (*) do (
set dirs[|find /i "%%~sa" >nul 2>nul ||(
echo "%%~sa" is a new folder
set flag=1
)
)
if %flag% equ 0 (
echo no new folders
)

batch-file incorporate another batch that copies modified files in directory to another directory

Here is what I've come up with, however I can't get the correct reference of xcopy in my code from what Aacini has provided in another post. cmd console will say it cannot find file "!lastName!!baseExt!" and then show that 0 files have been copied. It's not copying because I think the xcopy syntax will not allow for substitutions for the "source" "directory" relationship following xcopy.
Any help would be much appreciated. Thanks
#Echo Off
:: variables
set drive=C:\Users\me\Desktop\Test Source Folder
set backupcmd=xcopy /m /s /c /d /e /h /i /r /y /exclude:AutoFileCopy_Rev1.bat
set basename=
for %%a in ("C:\Users\me\Desktop\Test Source Folder") do (
if not defined baseName (
rem Is first name of first set
set baseName=%%~Na
set baseExt=%%~Xa
set lastname=%%~Na
) else (
rem Check if this name begin with same baseName
set name=%%~Na
for %%b in (!baseName!) do set name=!name:*%%b=!
if "!name!" neq "%%~Na" (
rem Yes: Is next name of same set
set lastName=%%~Na
) else (
rem No: Is first name of next set: copy previous set and pass to next one
%backupcmd% "!lastName!!baseExt!" "C:\Users\me\Desktop\Test Source Folder\! baseName!!baseExt!"
set baseName=%%~Na
set baseExt=%%~Xa
set lastName=%%~Na
)
)
)
rem Copy last set
Set _Delay=10
Set _Monitor=C:\Users\me\Desktop\Test Source Folder\
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
:_StartMon
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
echo ___ Backing up JobBoss files...
::%backupcmd% "C:\Users\john.weakley\Desktop\Test Source Folder" "C:\Users\me\Desktop\Test Destination Folder\"
::CALL "C:\users\me\Desktop\Test Source Folder\Test.bat"
ECHO ___ Checking for new file revisions...
%backupcmd% "!lastName!!baseExt!" "C:\Users\me\Desktop\Test Source Folder\!baseName!! baseExt!"
Echo.Backup Complete!
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
You need to enable delayed expansion in order to support !VAR! syntax.
Change your first line to:
#echo off & setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

How do I have a windows batch file look through hundreds of folders and move files around based on a list.txt?

I cant seem to get this to work. I need a batch file to go through a bunch of folders with files in them and move them to folders specified in the list .txt.
Basically I want it to do the following:
sample list.txt
folder1 file1
folder2 file1
and parse that so that i can:
copy C:\folder1\file1*.txt to destination folder
copy C:\folder2\file1*.txt to destination folder
etc
Here is what I have so far:
Main program:
echo off
set lines=0
for /f "tokens=1 delims=" %%a in (%CD%\list.txt) do (
echo %%a
echo 1 %SN% from EEN %EEN%
call :first %%a
echo 2 %SN% from EEN %EEN%
call :second %%a
echo 3 %SN% from EEN %EEN%
set /a lines+=1
)
echo %lines%
pause
goto :eof
:first
set EEN=%1
goto :eof
:second
set SN=%2
goto :eof
pause
list.txt (first column is folder name, second is file name):
DM5V37H WMC1F0077774
DM5V37H WMC1F0077711
DM5V37H WMC1F0086480
DM5V37H WMC1F0086372
DM5V37H WMC1F0077655
DM5V37H WMC1F0077770
What am I doing wrong?
I'm not sure about your references to SN and EEN, but I just tested this and it seems to work. The first section is a demonstration of how to access each item in a line read from the file, then the actual move operation is performed. I'm sure you can modify it to your needs.
#echo off
set lines=0
for /f "tokens=1,2 delims= " %%a in (list.txt) do echo %%a %%b&set /a lines+=1
echo Number of lines: %lines%
:: Perform move operation.
for /f "tokens=1,2 delims= " %%a in (list.txt) do (
if not exist %%a (md %%a)
move "%%b" "%%a\%%b"
)

Resources