2

My task is to create a script to copy dated sub folders from within folders to another location. The base folders are named 16 hex characters, each has a folder for the year, inside a folder for the month, and inside that a folder for a date, which contains binary (dump) files I need to copy out. There are about 50 folders with around 5 days across two months that I care about (for now), so I want to capture something like the following: C:\DUMPS\2401010153783FB6\2016\09\29*.*

Rather than doing a ton of copypaste script or manually trying to get all the folders I want (human error prone), I thought I should be able to create a BAT file to loop through an array of folder names and get at the files I care about. I found a very helpful piece in the answer from user DSS at the following: How to loop through array in batch?

My problem is that his example shows how to use CALL ECHO instead of just ECHO, but I want to use the string value as part of a folder name, not just print to the console. Here's the work-in-progress code I've developed:

SET COPYPATH=C:\Dumps
SET DESTPATH=D:\NewDumps
SET FOLDERNAME[0]=2401010153783FB6
SET FOLDERNAME[1]=2401010753BBBBCE
SET "X=1" # array start from index 1

:Looping
IF DEFINED FOLDERNAME[%X%] (
    CALL ECHO %%FOLDERNAME[%X%]%% REM Works great, I see the value of FOLDERNAME[0] on console.
    SET TEMPVAR= CALL ECHO %%FOLDERNAME[%X%]%% REM No good! Result is CALL ECHO.
    SET TEMPVAR= CALL %%FOLDERNAME[%X%]%% REM No good! Result is CALL X.
    SET TEMPVAR= %FOLDERNAME[%X%]% REM No good! Result is literal FOLDERNAME[0]; I want the value of FOLDERNAME[0].
    IF EXIST %TEMPVAR%\2016\09\28 (
        COPY %TEMPVAR%\2016\09\28 %DESTPATH%\%FOLDERNAME[%X%]%%\2016\09\28
    )
    IF EXIST %COPYPATH%\%FOLDERNAME%\2016\09\29 (
        COPY %COPYPATH%\%FOLDERNAME%\2016\09\29 %DESTPATH%\%FOLDERNAME%\2016\09\29
    )
    IF EXIST %COPYPATH%\%FOLDERNAME%\2016\09\30 (
        COPY %COPYPATH%\%FOLDERNAME%\2016\09\30 %DESTPATH%\%FOLDERNAME%\2016\09\30
    )
    IF EXIST %COPYPATH%\%FOLDERNAME%\2016\10\01 (
        COPY %COPYPATH%\%FOLDERNAME%\2016\10\01 %DESTPATH%\%FOLDERNAME%\2016\10\01
    )
    IF EXIST %COPYPATH%\%FOLDERNAME%\2016\10\02 (
        COPY %COPYPATH%\%FOLDERNAME%\2016\10\02 %DESTPATH%\%FOLDERNAME%\2016\10\02
    )
    SET /A "X+=1"
    GOTO :Looping
)

I would be fine with using a temporary variable for either path, or I could use the concatenated %COPYPATH%\%FOLDERNAME% syntax (which worked when I set this up for a one-off test, but now I want to loop it 50 times). Any advice is much appreciated!

bbkarim
  • 3
  • 2
Lee Crawford
  • 41
  • 1
  • 7

3 Answers3

0

how about

for /L %%a in (0,1,1) do (
 for %%b in (2016) do (
  for %%c in ("09 28" "09 29" "09 30" "10 01" "10 02") do (
   call :sub %%a %%b %%~c
  )
 )
)
...whatever, etc...
goto :eof

:sub
call set "foldername=%%foldername[%1]%%"
IF EXIST %COPYPATH%\%FOLDERNAME%\%2\%3\%4 (
 echo   COPY %COPYPATH%\%FOLDERNAME%\%2\%3\%4 %DESTPATH%\%FOLDERNAME%\%2\%3\%4
)
goto :eof

where the echo is there to show you what is proposed, delete that echo keyword to execute.

Note that you offer no explanation of why you switch from tempname to copypath\foldername in your code, so I've assumed it's incomplete substitution.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • Your method involves a nested loop, which adds complexity which is a concern when someone else tries to modify/use my script a year later. But I do like that it eliminates the copy-pasted folder name code. I made my script work with J Baoby's suggestion, but I will consider doing it your way as an alternate. Your assumption is correct; perhaps I could have explained better, but I wanted to 'show my work', since the folder naming was effectively the thing that was stumping me. – Lee Crawford Dec 05 '16 at 18:17
0

how about...

@echo off
setlocal enabledelayedexpansion

SET "COPYPATH=C:\Dumps"
SET "DESTPATH=D:\NewDumps"
SET "FOLDERNAME[0]=2401010153783FB6"
SET "FOLDERNAME[1]=2401010753BBBBCE"
rem set start to first item index, stop to last 
SET/a start=0, stop=1 


SET "DAYS=2016\09\28,2016\09\30,2016\10\01"


for /L %%i in (%start%,1,%stop%) do (
  echo !FOLDERNAME[%%i]!
  set "TEMPVAR=%COPYPATH%\!FOLDERNAME[%%i]!"
  set "DESTVAR=%DESTPATH%\!FOLDERNAME[%%i]!"
  for %%d in (%DAYS%) do (
    rem if it works, remove echo from line below
    IF EXIST "!TEMPVAR!\%%d" echo COPY "!TEMPVAR!\%%d" "!DESTPATH!\%%d"
  )

)

exit /B
elzooilogico
  • 1,659
  • 2
  • 17
  • 18
0

I suppose all your:

SET TEMPVAR=....

were attempts to save the result of a command into a variable Well I have to dissapoint you on that ... there is no possibility (yet) to assign directly the result of a command to a veriable in batch ( sorry ). Indirect ways do exist: for /f-loops, use of temporary file, ... but they could make your code more complex The command you are looking for is

call set tempvar=%%foldername[%x%]%%

The call is used to execute the commands you gave him as parameter inside a batch-file. So the command will look like (suppose x=0) set tempvar=%foldername[0]% and the call will just execute that (if x=0 off course...).

Good luck!

PS: consider @Magoo's answer to improve your batch script and @elzooilogico if you'd consider to use delayed epansion.

Community
  • 1
  • 1
J.Baoby
  • 2,167
  • 2
  • 11
  • 17
  • FYI, read this [Macros with parameters appended](http://www.dostips.com/forum/viewtopic.php?f=3&t=2518). And, I don't see nothing ugly in `for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"` nor `for /f "skip=2 tokens=3" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server" /V "InstalledInstances" /se @') do set "sqlInstance=%%A"` nor `for /f "tokens=1,2 delims=\" %%F in ('tasklist /V /NH /FI "imagename eq chrome.exe"') do ( ...` etc etc etc. It's powerful, useful, nice and YES, complex! – elzooilogico Dec 02 '16 at 19:01
  • maybe the term "ugly" is not the right choice but it would make his code complexer than if delayed expansion or `call` were used. Macros with parameters appended are another way to insert the result in a variable indeed. – J.Baoby Dec 02 '16 at 19:07
  • Complexer... I like that word, not as much the concept. I am a fan of simplicity; any complexity I can eliminate makes it easier for others to support later. I liked the simple loop I found in the example I drew from, but I'm open to complexer when simpler doesn't work. You are correct about my incomplete substitution; I wanted to use my code-paste to identify some of what I was in the process of trying out (and had seen not work as intended!) Your "CALL SET TEMPVAR=" syntax is exactly what I was trying to figure out. Thanks much! – Lee Crawford Dec 05 '16 at 17:23
  • It's my pleasure! If you have the time (and if you plan to expand your batch skills) make sure to check [`FOR` loops](http://ss64.com/nt/for.html) ([this link](http://www.robvanderwoude.com/for.php) is also great) and macros (see link from comment @elzooilogico). They help a lot. Good luck :) – J.Baoby Dec 05 '16 at 18:12