Search code examples
windowsbatch-filecmd

How to pushd mutliple folders on Windows batch


How can I include multiple paths? Like for example:

pushd C:\Users\Downloads\back\dotNet 
      C:\Users\Downloads\back\MySQL

And exclude every file with extension .log

7za.exe a -tzip -mx5 -x!\*.log* "C:\Users\Desktop\Downloadbak-%TODAY%.zip"
popd


ECHO.

PAUSE

Solution

  • There are actually 2 questions here:

    • pushd

    • 7z(a).exe

    Regarding pushd: a simple answer to your question is: It can't be done.
    pushd (push directory) and popd (pop directory) operate on a stack like structure - operations on a stack are push and pop

    • push has an argument and inserts it over the current stack top (the last element inserted), if any, and thus that becomes the stack top
    • pop simply takes the top of the stack out and making the next element of the stack (if any) its top

    So:

    • pushd inserts the current dir (%CD%) on the top of an internal stack and changes the current directory to the directory that it got as an argument
    • popd changes the current directory to the top of the (same) internal stack and also removes it from the stack

    But your desired behavior can be achieved by a sequence of pushd / popd commands, and there is one aspect that needs to be clear: pushd and popd commands order is reversed - explanation below:

    Let's assume that the internal stack is empty: you're located in ${DIR1} (this is a directory full path somewhere in your filesystem). As a note, Nix style variables (${...}) are just (directory) placeholders:

    • You execute:

      pushd ${DIR1}
      
    • This inserted ${DIR1} in the stack and changed your current dir to ${DIR2} (this is where you are located). Then you execute:

      pushd ${DIR3}
      
    • This inserted ${DIR2} on the stack (on top of ${DIR1}) and changed the current dir to ${DIR3} (this is where you are located). Now, you do your operations, and want to get back, so you execute:

      popd
      
    • This takes out ${DIR2} (the last one that was pushded) from the stack and changes the current directory to it (you will be located in ${DIR2}). And finally when executing again:

      popd
      
    • ${DIR1} is being removed from the stack (and thus the stack becomes empty - as it was at the beginning) and it changes the current directory to it, so you will be located in ${DIR1} just like before the 1st pushd command

    Now, regarding the 7zip executable (I see that you typed 7z a.exe, while on my computer is 7z.exe (just installed it)):

    It seems that your filter is perfectly fine, but it only strips the log files from he current directory, the sub directories seem to ignore the -x flag. So, I tested and it turns out that if I pass -r (recursive) it will also strip out all the .log files from sub-directories (although I can't explain why your pattern doesn't work with directories - maybe it only refers to base file names?).

    Here's the command (notice that I removed the \ before the *):

    7z.exe a -tzip -mx5 -r -x!*.log somefile.zip