Solved

Batch File: SET SourceFolder=!SourceFolder:%DestBasePath%=!

Posted on 2010-08-12
28
486 Views
Last Modified: 2012-05-10
Hi there,

In the following script, the line:
SET SourceFolder=!SourceFolder:%DestBasePath%=!

Does not work. I get the following output for that particular command line:
** SourceFolder=SourceFolder:=


SCRIPT TO FIX:
--------------------------------------------------------------------------
@echo off
setlocal enabledelayedexpansion

SET DisplayLines=40
MODE CON: COLS=150 LINES=!DisplayLines!


::SETTING STATIC VARIABLES
      SET CounterPath=0
      FOR /F "tokens=1-3 delims=:. " %%A in ('echo !time!') do set TheTime=%%A.%%B.%%C
      SET TheDate=!date!


::CREATING DATE VARIABLES
      For /f "Tokens=1-3 Delims=-" %%A in ('Echo !date!') do (set Year=%%A&& Set Month=%%B&& Set Day=%%C)


::READING INI FILES
      for /F "tokens=1,2 delims=^=" %%A in (Settings.ini) do SET Setting.ini_%%A=%%B
      for /F "tokens=1,2 delims=^>" %%A in (Paths.ini) do (
            SET /a CounterPath=!CounterPath! + 1
            SET SourceBasePath!CounterPath!=%%A
            SET DestBasePath!CounterPath!=%%B
      )


::SETUP HAS-BEEN FOLDER
      SET HasBeenFolder=!Setting.ini_HasBeenFolder!
      IF not exist !HasBeenFolder!  md !HasBeenFolder!
      IF not exist !HasBeenFolder!  ECHO.&&ECHO HAS-BEEN BASE FOLDER COULD NOT BE AUTOMATICALLY CREATED. PLEASE DO IT MANUALLY&&ECHO.&&PAUSE
      SET HasBeenFolder=!HasBeenFolder!\!Year!&&            IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!Month!&&            IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!Day!&&                  IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!TheTime!&&      IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL


::MOVE HAS-BEENS (FILE DELETED FROM SOURCE OR ABOUT TO BE REPLACED.) TO HAS-BEEN FOLDER.
FOR /L %%A in (1,1,!CounterPath!) do (
            SET SourceBasePath=!SourceBasePath%%A!
            SET DestBasePath=!DestBasePath%%A!
            ::
            FOR /F "delims=!" %%A in ('DIR /a-d /b /s !DestBasePath!') do (
                        ECHO --------------------------------
                        SET FileName=%%~nA%%~xA&& ECHO ** FileName=!FileName!
                        SET FilePath=%%~pA&&      ECHO ** FilePath=!FilePath!
                        ::SETUP DESTINATION FILE INFOS
                              SET DestFileFull=%%~fA&& ECHO ** DestFileFull=!DestFileFull!
                              SET DestFileSize=%%~zA&& ECHO ** DestFileSize=!DestFileSize!
                              SET DestFileDate=%%~tA&& ECHO ** DestFileDate=!DestFileDate!
                        ::SETUP SOURCE INFOS
                              FOR %%A in ("!DestFileFull!") do SET SourceFolder=%%~dA%%~pA
                              SET SourceFolder=!SourceFolder:%DestBasePath%=!
                              ECHO ** SourceFolder=!SourceFolder!
                              IF EXIST !SourceFileFull! (
                                    FOR %%A in ("!SourceFileFull!") do SET SourceFileSize=%%~zA
                                    FOR %%A in ("!SourceFileFull!") do SET SourceFileDate=%%~tA
                                    ECHO ** SourceFileSize=!SourceFileSize!
                                    ECHO ** SourceFileDate=!SourceFileDate!
                                    IF !SourceFileDate! NEQ !DestFileDate! ECHO ** DATE IS NOT THE SAME
                              ) ELSE (
                                    ECHO ** FILE DOES NOT EXIST AT SOURCE
                              )
                  )
      )

PAUSE
exit


Thanks for your help,
Rene
0
Comment
Question by:ReneGe
  • 10
  • 8
  • 8
  • +1
28 Comments
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33424248
Yes, you have a problem.  Basically, here is what you have:

FOR /L %%A in (1,1,!CounterPath!) do (
. . .
            SET DestBasePath=!DestBasePath%%A!
. . .
                              SET SourceFolder=!SourceFolder:%DestBasePath%=!

As you can see, you are referencing DetBasePath inside a large FOR loop where it's value was assigned.  As a result you can not reference it with %DestBasePath% as a result.  And sadly, the following does not work:

                              SET SourceFolder=!SourceFolder:!DestBasePath!=!

There's a bit to this script, so I'll study it a bit more and see if there's a way to get the effect you want.

~bp
0
 
LVL 43

Expert Comment

by:Steve Knight
ID: 33424260
Not quite sure what you are trying to do there but I presume maybe you mean:
  SET SourceFolder=!SourceFolder:%DestBasePath%!
i.e. not the second =?

Steve
0
 
LVL 43

Assisted Solution

by:Steve Knight
Steve Knight earned 20 total points
ID: 33424273
Good point, I guess time to split into subroutines and a CALL :whatever etc would you say?
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33424469
==>dragon-it, This script should get kind of large and I'd rather skip un-necessary "CALL" option if possible.

==>billprew, yes, I tried to acceive: SET SourceFolder=!SourceFolder:!DestBasePath!=! without result, so I tried with the %.

What I'm puzzled, is that I made a test script and this one works with the %

TEST SCRIPT:
-----------------------------------------------------------------------
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET BaseFolder=C:\Batchfiles
SET NewBaseFolder=C:\TestFolder

FOR /F "DELIMS=" %%A IN ('dir /b *.txt') do set File=%%~fA
SET Destination=!File:%BaseFolder%=!
SET Destination=!NewBaseFolder!!Destination!
echo !Destination!
pause
exit



I'll wait for your solution.

Cheers,
Rene
0
 
LVL 11

Accepted Solution

by:
Ben Personick earned 240 total points
ID: 33425331
@ReneGe

 CALL is not 'unnessessary'.

 (Also note in your test file you never ENDLOCAL!!  that will lead to poor beahvior of your script)
 
Delayed expantion and CAll will work quite similarly.  The difference being the call option is instaniating a second command environment whcih exists between a lable and the end of the file, or to a Command (EXE/Bat).

If the command is a bat the new environment exists between the begining of the file contents and the end of the file contents; if it is an EXE then the environment exists untill the command completes.

Called Lables and Commands can refer back to the original value %VARIABLE% and change that original variable as they like. and can substitute new values within it that will persist int he original environment.

Delayed Expantion is actually instating a new command environment within the parenthesis you put around the expantion and enabling the !! variables to hold the last value assigned to the %% variable.  Nothing more.  Basically besides enabling the !! variables, it considers your point you started the command on to be your batch file until it hits an EOF, exactly the same bhavior as "CALL :LABLE" except call lable would not care about parents.  so in essance it's a way to "CALL :LABLE" without naming a lable, and without having to find the lable, and without explicitly having to use an exit or GOTO :EOF to exit the secondary command environment.

SO what you wrote is yoru test batch file is exactly the same as doing this:

@ECHO OFF

SET BaseFolder=C:\Batchfiles
SET NewBaseFolder=C:\TestFolder

FOR /F "DELIMS=" %%A IN ('dir /b *.txt') do CALL :LOOP "%%~fA"
GOTO :EOF
:LOOP
SET Destination=%~1
SET Destination=%NewBaseFolder%%Destination%
echo %Destination%
pause
0
 
LVL 11

Expert Comment

by:Ben Personick
ID: 33426027
   You have alot of improperly terminated delayed expantion here.  please note that if you use too many delays sometimes you will have issues, reguardless, try te attached script, because all i did was properly terminate all your delayed expantion

Also I know what you are mentioning I haven't tested your looping yet with the fixed delayed expantion however because you weren't inside a delayed expantion I assume the issue was base you werten;t using a CALL, becvause I generally work without a delayed expantion I'm used to haveing to do this to get the effect you want:

CALL SET ThisVariable=%%ThisVariable%ThatVariable%%%

IN YOUR Case I would belivee it would be similar to this:

CALL SET SourceFolder=%%SourceFolder:!DestBasePath!=%%

@ECHO OFF
SETLOCAL EnableDelayedExpansion

SET "DisplayLines=40"
MODE CON: COLS=150 LINES=%DisplayLines%

::SETTING STATIC VARIABLES
	SET "CounterPath=0"
	FOR /F "Tokens=1-3 Delims=:" %%A in ("%TIME: =0%") DO SET "TheTime=%%A.%%B.%%C"
	:: DO you realise this date will be in the format "ddd MM\DD\YYYY" if you are in the NA Region settings..?
	SET "TheDate=%DATE%"
	:: A better Idea would be to use an ISO Date FOR all yrou Date handling.. YYYY-MM-DD Like this
	::SET TheDate=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%
	
::CREATING DATE VARIABLES
	FOR /F "Tokens=1-3 Delims=-" %%A in ("%TheDate%") DO SET "Year=%%A"&SET "Month=%%B"&SET "Day=%%C"
	::Seeing this you have already changed the date format settings in your OS.. ECHo only takes a split second longer but why bother??
	:: FOR my script testing:
	:: ECHO Y=%Year% M=%Month% D=%Day%
	:: SET "Year=%DATE:~10,4%"
	:: SET "Month=%DATE:~4,2%"
	:: SET "Day=%DATE:~7,2%"
	:: ECHO Y=%Year% M=%Month% D=%Day%
	
::READING INI FILES
	::Are you actually expecting to be in the local path where these settings are?
	::Generally speaking you shodul always write full directory paths instead of havingyoru batch file navigate directroies which can cause issues you did not expect!
	FOR /F "Tokens=1,2 Delims=^=" %%A in (C:\Admin\Setting.ini) do SET "Setting.ini_%%A=%%B"
	FOR /F "Tokens=1,2 Delims=^>" %%A in (C:\Admin\Paths.ini) do SET "SourceBasePath!CounterPath!=%%A"&SET "DestBasePath!CounterPath!=%%B"&SET /a CounterPath=!CounterPath!+1
	SET /a CounterPath=%CounterPath%-1
	
::SETUP HAS-BEEN FOLDER
	SET "HasBeenFolder=%Setting.ini_HasBeenFolder%"
	::No need to test FOR the folder the command will DO nothing if the folder already exists
	MD "%HasBeenFolder%">nul
	:: Why not just catch an error level or the error text instead of the following line?
	IF NOT EXIST "%HasBeenFolder%" ECHO.&ECHO HAS-BEEN BASE FOLDER "%HasBeenFolder%" COULD NOT BE AUTOMATICALLY CREATED. PLEASE DO IT MANUALLY&ECHO.&PAUSE
	:: Why not just use THIS command to BEGIN with above and skip your base foler creation??
	SET "HasBeenFolder=%Setting.ini_HasBeenFolder%\%Year%\%Month%\%Day%\%TheTime%"
	:: Why don't you care if there is still a permissions issue??
	MD "%HasBeenFolder%">nul
	
::MOVE HAS-BEENS (FILE DELETED FROM SOURCE OR ABOUT TO BE REPLACED.) TO HAS-BEEN FOLDER.
FOR /L %%A IN (1,1,%CounterPath%) DO (
    SET SourceBasePath=!SourceBasePath%%A!
    SET DestBasePath=!DestBasePath%%A!
    
    FOR /F "delims=!" %%A IN ('DIR /a-d /b /s !DestBasePath!') DO (
        ECHO --------------------------------
        SET FileName=%%~nA%%~xA& ECHO ** FileName=!FileName!
        SET FilePath=%%~pA&      ECHO ** FilePath=!FilePath!
        ::SETUP DESTINATION FILE INFOS
        SET DestFileFull=%%~fA& ECHO ** DestFileFull=!DestFileFull!
        SET DestFileSize=%%~zA& ECHO ** DestFileSize=!DestFileSize!
        SET DestFileDate=%%~tA& ECHO ** DestFileDate=!DestFileDate!
        ::SETUP SOURCE INFOS
        FOR %%A IN ("!DestFileFull!") DO (
			SET SourceFolder=%%~dA%%~pA
			SET SourceFolder=!SourceFolder:%DestBasePath%=!
			ECHO ** SourceFolder=!SourceFolder!
			IF EXIST !SourceFileFull! (
                FOR %%A IN ("!SourceFileFull!") DO (
					SET SourceFileSize=%%~zA
                    FOR %%A IN ("!SourceFileFull!") DO (
						SET SourceFileDate=%%~tA
                        ECHO ** SourceFileSize=!SourceFileSize!
                        ECHO ** SourceFileDate=!SourceFileDate!
                        IF !SourceFileDate! NEQ !DestFileDate! (
							ECHO ** DATE IS NOT THE SAME
						) ELSE (
                            ECHO ** FILE DOES NOT EXIST AT SOURCE
						)
					)
                )
			)
		)
    )
)
PAUSE

ENDLOCAL
GOTO :EOF

Open in new window

0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33426318
I noticed you never created  SourceFileFull variable, was that intentional?

Could you share some text of what this script is intended to do, I suspect there may be simplere ways to accomplish it.

~bp
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33428843
Also, not sure I understand this line:

   FOR /F "delims=!" %%A in ('DIR /a-d /b /s !DestBasePath!') do (

This appears to indicate that you have filenames with an exclamation point in the name (or path of), but that seems like an odd character to have in a filename?

I'm in the process of doing a bit of a rewrite of your original code just to give you some ideas, but have run into a couple of pieces that I didn't understand.

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33429566
==>billprew, !DestBasePath!' is a variable containing the destination path. I also see that SourceFileFull was not defined like you mentionned. so... I'll be back...

==>QCubed, thanks for your script analyse and suggestions, I will review it and provide you with feedback.

==>Steve, Thanks for your feedback

Cheers,
Rene
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33429750
billprew,

Here, I added "SourceFileFull". However, "SET SourceFolder=!SourceFolder:%DestBasePath%=!" is defined before "SourceFileFull" so I sill have an issue with defining  "SET SourceFolder=!SourceFolder:%DestBasePath%=!"

Cheers,
Rene


@echo off
setlocal enabledelayedexpansion

SET DisplayLines=40
MODE CON: COLS=150 LINES=!DisplayLines!


::SETTING STATIC VARIABLES
      SET CounterPath=0
      FOR /F "tokens=1-3 delims=:. " %%A in ('echo !time!') do set TheTime=%%A.%%B.%%C
      SET TheDate=!date!


::CREATING DATE VARIABLES
      For /f "Tokens=1-3 Delims=-" %%A in ('Echo !date!') do (set Year=%%A&& Set Month=%%B&& Set Day=%%C)


::READING INI FILES
      for /F "tokens=1,2 delims=^=" %%A in (Settings.ini) do SET Setting.ini_%%A=%%B
      for /F "tokens=1,2 delims=^>" %%A in (Paths.ini) do (
            SET /a CounterPath=!CounterPath! + 1
            SET SourceBasePath!CounterPath!=%%A
            SET DestBasePath!CounterPath!=%%B
      )


::SETUP HAS-BEEN FOLDER
      SET HasBeenFolder=!Setting.ini_HasBeenFolder!
      IF not exist !HasBeenFolder!  md !HasBeenFolder!
      IF not exist !HasBeenFolder!  ECHO.&&ECHO HAS-BEEN BASE FOLDER COULD NOT BE AUTOMATICALLY CREATED. PLEASE DO IT MANUALLY&&ECHO.&&PAUSE
      SET HasBeenFolder=!HasBeenFolder!\!Year!&&            IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!Month!&&            IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!Day!&&                  IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!TheTime!&&      IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL


::MOVE HAS-BEENS (FILE DELETED FROM SOURCE OR ABOUT TO BE REPLACED.) TO HAS-BEEN FOLDER.
FOR /L %%A in (1,1,!CounterPath!) do (
            SET SourceBasePath=!SourceBasePath%%A!
            SET DestBasePath=!DestBasePath%%A!
            ::
            FOR /F "delims=!" %%A in ('DIR /a-d /b /s !DestBasePath!') do (
                        ECHO --------------------------------
                        SET FileName=%%~nA%%~xA&& ECHO ** FileName=!FileName!
                        SET FilePath=%%~pA&&      ECHO ** FilePath=!FilePath!
                        ::SETUP DESTINATION FILE INFOS
                              SET DestFileFull=%%~fA&& ECHO ** DestFileFull=!DestFileFull!
                              SET DestFileSize=%%~zA&& ECHO ** DestFileSize=!DestFileSize!
                              SET DestFileDate=%%~tA&& ECHO ** DestFileDate=!DestFileDate!
                        ::SETUP SOURCE INFOS
                              FOR %%A in ("!DestFileFull!") do SET SourceFolder=%%~dA%%~pA
                              SET SourceFolder=!SourceFolder:%DestBasePath%=!
                              SET SourceFileFull=!SourceFolder!!FileName!
                              ECHO ** SourceFolder=!SourceFolder!
                              IF EXIST !SourceFileFull! (
                                    FOR %%A in ("!SourceFileFull!") do SET SourceFileSize=%%~zA
                                    FOR %%A in ("!SourceFileFull!") do SET SourceFileDate=%%~tA
                                    ECHO ** SourceFileSize=!SourceFileSize!
                                    ECHO ** SourceFileDate=!SourceFileDate!
                                    IF !SourceFileDate! NEQ !DestFileDate! ECHO ** DATE IS NOT THE SAME
                              ) ELSE (
                                    ECHO ** FILE DOES NOT EXIST AT SOURCE
                              )
                  )
      )

PAUSE
exit



0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33429765
==> This appears to indicate that you have filenames with an exclamation point in the name (or path of),
==> but that seems like an odd character to have in a filename?

Are there actually exclamation points in the filenames?

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33429802
No, the explamation points are to define what ever is in between them as a variable.
0
 
LVL 51

Assisted Solution

by:Bill Prew
Bill Prew earned 240 total points
ID: 33429917
Okay, then the DELIMS is a mistake in the following?

   FOR /F "delims=!" %%A in ('DIR /a-d /b /s !DestBasePath!') do (

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33431919
==> billprew, now I get the miss-comminucation, ! is not a file delemiter and effectivly will screw up the rest. This was a finger glitch from my part.

==> QCubed I have reviewed your suggestions and this was very edicationnal.
Are you saying that with the following, I canextract date with whatever Windows date format?
%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%

-------------------------------------------------------------------------------------------------------------------------

I figured it out.

Since !DestBasePath! was containing the right value but %DestBasePath% was empty, I had to define a new variable within the same FOR command.

@echo off
setlocal enabledelayedexpansion

SET DisplayLines=40
MODE CON: COLS=150 LINES=!DisplayLines!


::SETTING STATIC VARIABLES
      SET CounterPath=0
      FOR /F "tokens=1-3 delims=:. " %%A in ('echo !time!') do set TheTime=%%A.%%B.%%C
      SET TheDate=!date!


::CREATING DATE VARIABLES
      For /f "Tokens=1-3 Delims=-" %%A in ('Echo !date!') do (set Year=%%A&& Set Month=%%B&& Set Day=%%C)


::READING INI FILES
      for /F "tokens=1,2 delims=^=" %%A in (Settings.ini) do SET Setting.ini_%%A=%%B
      for /F "tokens=1,2 delims=^>" %%A in (Paths.ini) do (
            SET /a CounterPath=!CounterPath! + 1
            SET SourceBasePath!CounterPath!=%%A
            SET DestBasePath!CounterPath!=%%B
      )


::SETUP HAS-BEEN FOLDER
      SET HasBeenFolder=!Setting.ini_HasBeenFolder!
      IF not exist !HasBeenFolder!  md !HasBeenFolder!
      IF not exist !HasBeenFolder!  ECHO.&&ECHO HAS-BEEN BASE FOLDER COULD NOT BE AUTOMATICALLY CREATED. PLEASE DO IT MANUALLY&&ECHO.&&PAUSE
      SET HasBeenFolder=!HasBeenFolder!\!Year!&&            IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!Month!&&            IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!Day!&&                  IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL
      SET HasBeenFolder=!HasBeenFolder!\!TheTime!&&      IF not exist "!HasBeenFolder!" md "!HasBeenFolder!">NUL


::MOVE HAS-BEENS (FILE DELETED FROM SOURCE OR ABOUT TO BE REPLACED.) TO HAS-BEEN FOLDER.
FOR /L %%A in (1,1,!CounterPath!) do (
            SET SourceBasePath=!SourceBasePath%%A!
            SET DestBasePath=!DestBasePath%%A!
            ::
            FOR /F "delims=" %%A in ('DIR /a-d /b /s !DestBasePath!') do (
                        ECHO --------------------------------
                        SET FileName=%%~nA%%~xA&& ECHO ** FileName=!FileName!
                        SET FilePath=%%~pA&&      ECHO ** FilePath=!FilePath!
                        ::SETUP DESTINATION FILE INFOS
                              SET DestFileFull=%%~fA&& ECHO ** DestFileFull=!DestFileFull!
                              SET DestFileSize=%%~zA&& ECHO ** DestFileSize=!DestFileSize!
                              SET DestFileDate=%%~tA&& ECHO ** DestFileDate=!DestFileDate!
                        ::SETUP SOURCE INFOS
                              FOR %%A in ("!DestFileFull!") do SET SourceFolder=%%~dA%%~pA
                              ECHO ** SourceFolder=!SourceFolder! === !DestBasePath!
                              SET DestBasePath1=!DestBasePath!
                              SET SourceFolder=!SourceFolder:%DestBasePath1%=!
                              SET SourceFileFull=!SourceFolder!!FileName!
                              ECHO ** SourceFolder=!SourceFolder!
                              IF EXIST !SourceFileFull! (
                                    FOR %%A in ("!SourceFileFull!") do SET SourceFileSize=%%~zA
                                    FOR %%A in ("!SourceFileFull!") do SET SourceFileDate=%%~tA
                                    ECHO ** SourceFileSize=!SourceFileSize!
                                    ECHO ** SourceFileDate=!SourceFileDate!
                                    IF !SourceFileDate! NEQ !DestFileDate! ECHO ** DATE IS NOT THE SAME
                              ) ELSE (
                                    ECHO ** FILE DOES NOT EXIST AT SOURCE
                              )
                  )
      )

PAUSE
exit
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 51

Expert Comment

by:Bill Prew
ID: 33433804
==> %DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%

This assumes that your date is in a format of aaa bb/cc/dddd

and will always extract as dddd-bb-cc

If your date were formatted at say just mm/dd/yyyy then this will not work.

I do have a routine that I use to account for various formats that can be set in Windows and this change the display of the %DATE% variable, I can include that small routine in my rewrite if you like?

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33433830
Yes plz thanks
0
 
LVL 11

Expert Comment

by:Ben Personick
ID: 33433966
I only used that for me, I assumed you knew what your date format was, and I made mention that that code will only wok if your region is North America, if it is not you need to change the code to work with your output format.  you can find out your output format by typing:

ECHO "%DATE%" at the command prompt and looking at the output.

in North America the format will be:

"ddd MM/DD/YYYY"
(here is an example with today's date)
"Fri 08/13/2010"

Since I knwo this and I only work in NA, I just use the code:

%DATE:~4,2% to grab the current Month (Grabs character 4 to character 6)
%DATE:~7,2% to grab the current Day (Grabs character 7 to character 9)
%DATE:~10,4% to grab the current Year (Grabs character 10 to character 14)
( OR )%DATE:~-4% to grab the current year (Grabs THE LAST 4 characters)
0
 
LVL 11

Expert Comment

by:Ben Personick
ID: 33434001
I noticed you went back to this code:

 FOR /F "tokens=1-3 delims=:. " %%A in ('echo !time!') do set TheTime=%%A.%%B.%%C

Why bother echoing???  It only takes more timeup.  You can just parse the variable as a string.

This will work exactly the same, I use it in my code, more importantly it will give you a leading 0, your code will sometimes (between 12:00 AM and 9:59 AM) give you a leading space because it shows the time as " 0:00:00.00" to " 9:59:59:99" thereafter it will display the missing digit.  that is why you should use this instead:

FOR /F "Tokens=1-3 Delims=:." %%A ("%Time%") DO SET TheTime=%%A.%%B.%%C


Not only does this allow you to skip an unnecessary echo command, but it turns the leading space into a 0 which allows windows to sort the information properly, and ensures you don;t have an errant space in something.
0
 
LVL 11

Expert Comment

by:Ben Personick
ID: 33434058
 I notice you didn't really keep any of the improvements I pout in the other sections either...

  I know you said you were very concerned about the script taking a long time to execute so I tried to make as many statement be single-lined as possible.

  I tested all portions functionality except for the final looping which I haven't had time to do yet, you should consider the changes I made, because you should avoid using delayed expansion to save more time when it is unneeded.

  I suppose that is the crux of anything though, and i know I'm 'one to talk' because I like to be verbose.. lol.

Also, exit at the end of the file instead of nothing or GOTO :EOF is a poor choice because you can accidentally end up closing the command prompt you're running things in.
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33434074
==>QCubed, Thanks for explaining. While at it, is there a code the will grab the last (let's say) 5 caracters?
0
 
LVL 11

Expert Comment

by:Ben Personick
ID: 33434248
Only of a variable.  that is why I do through pains in my code to put everythign in variable form.

Assuming you have a Variable named "VariableName"  and it's been set to the Value 1234567890

(as in SET "VariableName=1234567890")

Then you can do this to USE only the last 5 characters:

%VariableName:~-5%

Whatever you are doing with the variable it will resolve to this:  67890

AND you can use this to USE only the first five characters:

%VariableName:~0,5%

Whatever you are doing with the variable it will resolve to this: 12345

Also you can use this to USE only the characters from position 3 through position 7:
%VariableName:~3,5%

Whatever you are doing with the variable it will resolve to this: 45678
0
 
LVL 10

Author Closing Comment

by:ReneGe
ID: 33434673
Thanks guys for your help and contribution.

I'll have more questions about this script but I'll create new threads so you can get more points.

Thanks again and cheers,
Rene
0
 
LVL 11

Expert Comment

by:Ben Personick
ID: 33434745
Sweet, thanks vMuch glad I could be of so much help, Bill is also a top-notch Expert.  Please remember to post links to the related questions on this question and back to this question on the other ones (just good practice)   =)
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33434752
== QCubed

Thanks for the kind words, appreciated.

~bp
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33434946
Okay, I'd suggest you take a look at this to see what you can learn, and of course, see if it works!  You'll probably notice other changes from your code, but here are a few notes:

Don't use !var! when you can use %var%.  Typically you only need to use the !var! delayed expansion when you are referencing a variable inside a code block where the variablt was set.  This is most commonly a FOR.

Don't use :: for comment lines, use REM.  :: is a kludge for comments, and when used inside a FOR loop can sometimes cause problems.  REM is the proper languages supported way for comments to be entered, and as such a future version of the command interpreter may remove the hole that allows :: to serve as comments.

In FOR /F loops there's no needs to ECHO a variable, just reference it in quotes.

I added my routine to get month, day and year independently of system date format.

The MD command will create all needed intermediate folders, no need to build them up manually one at a time, level by level.

I am really not a fan of multiple commands on a single line unless it adds to readability.  I prefer to slit these onto separate lines.  This is a somewhat personal preference, but take a look at how it looks each way.  Also, I find that the "simpler" that code looks when reading it, the easier it is to understand quickly, and the easier it is to maintain in the future, without breaking it!

I did some assorted cleanups and fixes in the main FOR loop getting the file names and dates, etc.  I resisted the urge to remove the extra variables being SET, since I suspect you are planning to build on this going forward.

Clearly you will note quite different styles and techniques between QCubed code and mine.  In some cases there may technical or software engineering reasons why one approach can be better than another, but in general a large amount of it is personal.  I always find it interesting to see how other people approach things in different ways than I do, and try and learn from it.  

Speaking of which, you'll notice I prefer quite a bit smaller indent levels than you gents.  With current editors typically language aware and often showing where blocks begin and end, or showing vertical guide lines.  As a result, I go with 2 or 3 spaces per indent level rather than the 6 or 8 some folks prefer.  Clearly this is a very personal preference and different people prefer different levels.  Withing a software project, or better still withing a company, I prefer things like this to be called out in a programming standards guide, so all code does things like indentation, naming conventions, capitalization the same.  But up here on EE where each problem is a small atomic solution, we all bring our personal preferences to the table.

Hope this helps.

~bp
@echo off
setlocal EnableDelayedExpansion
 
SET DisplayLines=40
MODE CON: COLS=150 LINES=%DisplayLines%
 
REM SETTING STATIC VARIABLES
SET CounterPath=0
FOR /F "tokens=1-3 delims=:. " %%A in ("%TIME%") do (
   set TheTime=%%A.%%B.%%C
)
 
REM Get month, day, and year (works on any date format)
call :GetDate "Month" "Day" "Year"
 
REM READING INI FILES
for /F "tokens=1,2 delims=^=" %%A in (Settings.ini) do (
   SET Setting.ini_%%A=%%B
   )
for /F "tokens=1,2 delims=^>" %%A in (Paths.ini) do (
   SET /a CounterPath=+1
   SET SourceBasePath!CounterPath!=%%A
   SET DestBasePath!CounterPath!=%%B
)
 
REM SETUP HAS-BEEN FOLDER
SET HasBeenFolder=!Setting.ini_HasBeenFolder!
IF not exist %HasBeenFolder% md %HasBeenFolder%
IF not exist %HasBeenFolder% (
   ECHO.
   ECHO HAS-BEEN BASE FOLDER COULD NOT BE AUTOMATICALLY CREATED. PLEASE DO IT MANUALLY
   ECHO.
   PAUSE
)
IF not exist "%HasBeenFolder%\%Year%\%Month%\%Day%\%TheTime%\" md "%HasBeenFolder%\%Year%\%Month%\%Day%\%TheTime%">NUL
 
REM MOVE HAS-BEENS (FILE DELETED FROM SOURCE OR ABOUT TO BE REPLACED.) TO HAS-BEEN FOLDER.
FOR /L %%A in (1,1,!CounterPath!) do (
   SET SourceBasePath=!SourceBasePath%%A!
   SET DestBasePath=!DestBasePath%%A!
   REM
   FOR /F "delims=" %%A in ('DIR /a-d /b /s !DestBasePath!') do (
      ECHO --------------------------------
      SET FileName=%%~nA%%~xA
      SET FilePath=%%~pA
      ECHO ** FileName=!FileName!
      ECHO ** FilePath=!FilePath!
      REM SETUP DESTINATION FILE INFOS
      SET DestFileFull=%%~fA
      SET DestFileSize=%%~zA
      SET DestFileDate=%%~tA
      ECHO ** DestFileFull=!DestFileFull!
      ECHO ** DestFileSize=!DestFileSize!
      ECHO ** DestFileDate=!DestFileDate!
      REM SETUP SOURCE INFOS
      CALL SET SourceFileFull=%%DestFileFull:!DestBasePath!=!SourceBasePath!%%
      ECHO ** SourceFileFull=!SourceFileFull!
      IF EXIST "!SourceFileFull!" (
         FOR %%B in ("!SourceFileFull!") do (
            SET SourceFileSize=%%~zB
            SET SourceFileDate=%%~tB
         )
         ECHO ** SourceFileSize=!SourceFileSize!
         ECHO ** SourceFileDate=!SourceFileDate!
         IF !SourceFileDate! NEQ !DestFileDate! ECHO ** DATE IS NOT THE SAME
      ) ELSE (
         ECHO ** FILE DOES NOT EXIST AT SOURCE
      )
   )
)
 
PAUSE
exit
 
REM Support subroutine to get date components
:GetDate [month-variable] [day-variable] [year-variable]
  REM Get date format settings from registry
  rem For REG.EXE 3.0 (Windows XP) and later versions
  for /F "tokens=3" %%A in ('reg query "HKCU\Control Panel\International" /v iDate 2^>NUL') do set "iDate=%%A"
  for /F "tokens=3" %%A in ('reg query "HKCU\Control Panel\International" /v sDate 2^>NUL') do set "sDate=%%A"
  rem For earlier REG.EXE versions
  rem for /F "tokens=3" %%A in ('reg query "HKCU\Control Panel\International\iDate" 2^>NUL') do set "iDate=%%A"
  rem for /F "tokens=3" %%A in ('reg query "HKCU\Control Panel\International\sDate" 2^>NUL') do set "sDate=%%A"
 
  REM Get the current system date (ignore day name if present)
  for %%A in (%Date%) do set "Today=%%A"
 
  REM Parse current date based on delimiter from registry, and assign to desired user variable
  for /F "tokens=1-3 delims=%sDate%" %%A in ("%Today%") do (
    if "%iDate%"=="0" set "%~2=%%B" & set "%~1=%%A" & set "%~3=%%C"
    if "%iDate%"=="1" set "%~2=%%A" & set "%~1=%%B" & set "%~3=%%C"
    if "%iDate%"=="2" set "%~2=%%C" & set "%~1=%%B" & set "%~3=%%A"
  )
  exit /b
)

Open in new window

0
 
LVL 10

Author Comment

by:ReneGe
ID: 33438716
Billprew this was very educative.

Could you please explain:
CALL SET SourceFileFull=%%DestFileFull:!DestBasePath!=!SourceBasePath!%%

Thanks,
Rene
0
 
LVL 11

Expert Comment

by:Ben Personick
ID: 33438971
I can explain.

As I mentioned in my Comment (08/12/10 08:48 PM, ID: 33426027) Above:

When you want to set a variable to show a portion of itself or replace a portion of itself as defined by another variable you actually need to CALL the Set command.  That functionality has nothing to do with Delayed expantion it's just how the command environment works.

The reason for this is because when you CALL set it takes the first variable and passes it as a parameter to the second variable, while when you do NOT call it doesn't understand that there IS a second variable to manipulate.

(Hence part of the reason I prefer CALLs to working with delayed expansion, but there is no reason you can't do both in a batch file, and it certainly can be very useful to use delayed expansion instead of calls at times or vice verse.)

Why this works this way:

Whenever you CALL a Command or other executable, the command environment you are in pauses, spawns a new command process, and passes any variables you specify to the new command process.

When you call a command and pass it a variable with another variable inside it it will evaluate the variable inside (assume you formatted correctly) before evaluating the variable on the outside.  where as if you DO NOT CALL you will evaluate the variable front forwards, so the best you could hope for via that method is to have a string of variables added together.

Was that clear for you?

~Q



 PS I have an updated version as well since Bill posted his I will do likewise.
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33442034
Hey guys,

Thanks for all your help and teachings.

It was very educative.

Here is the link for my follow-up question:
http://www.experts-exchange.com/Programming/Languages/Scripting/Shell/Batch/Q_26404456.html

Thanks again & cheers,
Rene
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

This article will show, step by step, how to integrate R code into a R Sweave document
This is about my first experience with programming Arduino.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now