如何在Windows批处理上推送多个文件夹

时间:2015-09-04 19:48:33

标签: windows batch-file cmd

如何添加多条路径? 例如:

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

并排除扩展名为.log

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


ECHO.

PAUSE

3 个答案:

答案 0 :(得分:3)

这里实际上有两个问题:

  • PUSHD

  • 7Z(a)中的.exe

关于 pushd :对您的问题的简单回答是:无法完成 pushd (推送目录)和 popd (pop目录)在堆栈上运行 - 堆栈上的操作是 push pop - push有一个参数并将其插入当前堆栈顶部(插入的最后一个元素)(如果有的话),因此它成为堆栈顶部,而pop只是将堆栈的顶部输出并生成下一个元素堆栈(如果有的话)它的顶部。

因此, pushd 将当前目录(%CD%)插入内部堆栈的顶部,并将当前目录更改为它作为参数获取的目录,同时 popd 将当前目录更改为(相同)内部堆栈的顶部,并将其从堆栈中删除。

但是你可以通过一系列 pushd / popd 命令实现你想要的行为,这里有一个方面需要明确 pushd 命令和 popd 命令顺序颠倒过来:我将在下面解释:

我们假设内部堆栈为空:您位于%dir1%(这是文件系统中某个目录完整路径)。

  • 执行:

    pushd %dir2%
    
  • 这会在堆栈中插入%dir1%,并将当前目录更改为%dir2%(这是您所在的位置)。现在执行:

    pushd %dir3%
    
  • 这在堆栈上插入%dir2%(在%dir1%之上)并将当前目录更改为%dir3%(这是您所在的位置)。现在,您进行操作,并希望返回,因此执行:

    popd
    
  • 这会从堆栈中取出%dir2%(最后一个 pushd ed)并将当前目录更改为它(您将位于%dir2%中)。最后再次执行时:

    popd
    
  • %dir1%正在从堆栈中删除(因此堆栈在开始时变为空)并且它将当前目录更改为它,因此您将位于%dir1%之前,就像在第1个之前一样 pushd 命令。

现在,关于7zip可执行文件(我看到你输入了7z a .exe,而在我的计算机上是7z.exe(刚安装它)):

看起来您的过滤器非常好,但它只从当前目录中删除日志文件,子目录似乎忽略了-x标志。所以,我进行了测试,结果发现如果我通过-r(递归),它也会从子目录中删除所有 .log 文件(尽管我无法解释)为什么你的模式不适用于目录 - 也许它只是指基本文件名?)。

这是命令(请注意我在\之前移除了*):

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

答案 1 :(得分:1)

简单回答:你不能。

pushd 将当前目录更改为您提供的目录,在更改目录之前,它将当前目录保存在堆栈中。

但是只有一个"当前"因此,为pushd命令提供多个目录是没有意义的(也无法工作)。

答案 2 :(得分:0)

到现场有点晚,但是无论如何都去了。以下是Windows批处理脚本中堆栈数据结构的实现。

功能:

  • 使用堆栈之前,必须先调用:InitializeStack 子例程。
  • 通过调用:Push 子例程将项目压入堆栈。
  • 通过调用:Pop 子例程从堆栈中弹出项目。
  • 变量 $ Count 将始终包含堆栈中的项目数。
  • 变量 $ Top 将始终包含添加到堆栈中的最新项目。
  • 变量 $ Bottom 将始终包含添加到堆栈中的第一项。
  • 您可以通过调用:DumpStack 子例程来转储堆栈的内容。
  • 您可以在堆栈中推送的项目类型是可以存储在变量中的任何内容。例如, Call:Push“ String 1” Call:Push“%1” Call:Push“%MyVariable%” 等。

我使用批处理文件中的堆栈来跟踪子例程调用。批处理文件中的每个子例程都以 Call:Push%0 开头,它将当前子例程的名称压入堆栈,并以 Call:Pop 结尾。

对于批处理脚本,有些人可能会觉得有些过头,但是我很喜欢创建它,我希望有人会发现它有用,享受

@Echo Off
Cls
SetLocal
SetLocal EnableExtensions
SetLocal EnableDelayedExpansion

Call :InitializeStack

Call :Push "String 1"
Call :Push "String 2"
Call :Push "String 3"
Call :Pop

Echo Total items in stack = !$Count!
Echo Top of stack         = !$Top!
Echo Bottom of stack      = !$Bottom!
Call :DumpStack

Goto End

:InitializeStack
:------------------------------------------------------------
Set "$Stack[0]=0"
Set "$Count=!$Stack[0]!"
Set "$Top="
Set "$Bottom="
Exit /b

:DumpStack
:------------------------------------------------------------
If !$Stack[0]! EQU 0 (
  Echo Stack is empty.
) Else (
  Echo.
  Echo Stack Dump
  Echo ----------
  For /l %%a In (!$Stack[0]!,-1,1) Do (Echo !$Stack[%%a]!)
)
Exit /b

:Push <String>
:------------------------------------------------------------
Set /a "$Stack[0]+=1"
Set "$Count=!$Stack[0]!"
Set "$Top=%~1"
Set "$Bottom=!$Stack[1]!"
Set "$Stack[!$Stack[0]!]=!$Top!"
Exit /b

:Pop
:------------------------------------------------------------
If !$Stack[0]! EQU 0 (
  Echo "Stack is empty."
) Else (
  Set "$Stack[!$Stack[0]!]="
  Set /a "$Stack[0]-=1"
  Set "$Count=!$Stack[0]!"
  If !$Stack[0]! GTR 0 (
    For %%a In (!$Stack[0]!) Do Set "$Top=!$Stack[%%a]!"
    Set "$Bottom=!$Stack[1]!"
  ) Else (
    Set "$Top="
    Set "$Bottom="
  )
)Exit /b

:End

要将所有路径放置在堆栈上,请使用以下命令:

For %%a In ("<path1>" "<path2>") Do Call :Push "%%~a"

要对堆栈中的项目执行操作,可以使用:

For /l %%a In (!$Stack[0]!,-1,1) Do (pushd !$Stack[%%a]!)