RDunkley
RDunkley

Reputation: 15

For Loop with nested Forfiles only works if batch is in same folder

My code works fine when I have the .bat in the "%USERPROFILE%\Downloads" folder which is where I want it to look for .zip files. I just can't work out how to point here if the .bat lives elsewhere. If I move the .bat to another location there is no output, the file doesn't appear to do anything.

I have tried adding the following before the [FOR] command but this doesn't seem to help. Any advice would be greatly appreciated.

CD %USERPROFILE%\Downloads

Here is my code...

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%F in (EPSG*.zip) do (
 for /F "tokens=1,* delims=|" %%K in ('
  forfiles /p "%USERPROFILE%\Downloads" /m "%%~F" /c "cmd /c echo @FDATE^|@FTIME"
    ') do (
   setlocal EnableDelayedExpansion  
     set "name=%%~F"
     set "timestamp=%%~K %%L"
     set "timestamp=!timestamp:/=-!"
     set "timestamp=!timestamp::=.!"
     set "destpath=%USERPROFILE%\Downloads\Nearmap Downloads\!timestamp!"
     powershell -command "Expand-Archive -Force -Path '!name!' -DestinationPath '!destpath!'"
     endlocal
    )
)
pause

Upvotes: 1

Views: 473

Answers (3)

Magoo
Magoo

Reputation: 80023

@echo off
setlocal EnableExtensions DisableDelayedExpansion
PUSHD "%USERPROFILE%\Downloads"
...
)
POPD
pause

Once a PUSHD instruction is executed, the argument becomes the current directory (so you need not include it in the forfiles line...) until the matching POPD is executed, restoring the original current-directory.

And then if yourbatch.bat is placed in any directory on the PATH you should be able to execute it by simply typing yourbatch at the prompt.

Upvotes: 0

Compo
Compo

Reputation: 38604

I'm not sure why you've added a nested for loop containing the resource intensive forfiles command, you should be able to do it more like this:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "sourcepath=%UserProfile%\Downloads"
Set "destpath=%sourcepath%\Nearmap Downloads"
For %%A In ("%sourcepath%\EPSG*.zip")Do (Set "timestamp=%%~tA"
    SetLocal EnableDelayedExpansion
    Set "timestamp=!timestamp:/=-!"
    Powershell -NoProfile -Command "Expand-Archive -Force -Path '%%A' -DestinationPath '%destpath%\!timestamp::=.!'"
    EndLocal)

As you're running the a script anyhow, I'm a little baffled why you didn't do it all within the same .ps1 script!

Upvotes: 0

michael_heath
michael_heath

Reputation: 5372

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "rootdir=%USERPROFILE%\Downloads"

for %%F in ("%rootdir%\EPSG*.zip") do (
    for /F "tokens=1,* delims=|" %%K in ('
     forfiles /p "%rootdir%" /m "%%~nxF" /c "cmd /c echo @FDATE^|@FTIME"
    ') do (
        set "name=%%~F"
        set "timestamp=%%~K %%L"

        setlocal EnableDelayedExpansion
        set "timestamp=!timestamp:/=-!"
        set "timestamp=!timestamp::=.!"
        set "destpath=!rootdir!\Nearmap Downloads\!timestamp!"
        powershell -command "Expand-Archive -Force -Path '!name!' -DestinationPath '!destpath!'"
        endlocal
    )
)
  • The basic for loop changed to use a full path.
  • The forfiles uses a searchmask of the current zip filename by using for modifiers of nx.
  • Set rootdir to store the root directory to avoid some duplication, so that change of root directory can be changed in the 1 set value.
  • setlocal EnableDelayedExpansion moved to where needed and not before.

Upvotes: 1

Related Questions