在批处理文件中遍历文件夹和文件?

在批处理文件中遍历文件夹和文件?

我的情况如下。一个项目的目标是将一些附件迁移到另一个系统。

这些附件将位于父文件夹中,例如“Folder 0 ”(请参阅这个问题的图表为了更好地理解),它们将被压缩。

我希望我的批处理脚本像这样被调用:

BatchScript.bat "c:\temp\usd\Folder 0"

我正在使用它7za.exe作为命令行提取工具。

我希望批处理脚本遍历“ Folder 0”的子文件夹,并将所有包含的 ZIP 文件提取到各自的文件夹中。

解压的文件必须与各自的 ZIP 文件位于同一文件夹中。因此,“ File 1.zip”中包含的文件需要位于“ Folder 1”中,依此类推。

我读过FOR...DO命令Windows XP Professional Product Documentation - Using Batch Files

这是我的脚本:

@ECHO OFF

FOR /D %folder IN (%%rootFolderCmdLnParam) DO 
    FOR %zippedFile IN (*.zip) DO 7za.exe e %zippedFile

我猜想在调用 7za.exe e %zippedFile 进行文件提取之前,我还需要在更改实际目录,但我不知道如何在该批处理文件中执行此操作(尽管我知道如何在命令行中执行此操作,即使我知道它是相同的指令“cd”)。

编辑#1

下面给出的答案都接近我需要的。但由于某些未知原因,有时当我给出一个参数时,批处理文件不会执行任何操作,而是让我回到提示。

我大约有 15 年没有编写过批处理文件了,所以我完全忘记了背后的逻辑等等。

有人可以帮忙吗?

编辑#2

似乎无法确定的是,批处理文件脚本无法处理带有空格字符的文件夹名称。你们中有人能确认并提出解决方案吗?

我在这里完全失明了......谢谢你的帮助!=)

编辑#3

我需要完全递归的解决方案,因为我不知道将要使用该解决方案的目录结构。抱歉之前没有提到。

编辑#4

我受到了您和其他人的所有答案的启发,得出了以下内容(有效率为 98%):

@echo off

setlocal enableextensions enabledelayedexpansion

rem
rem Display instructions when no parameter is given.
rem
if "%1" equ "" (
    echo Syntaxe : od.bat ^<directory mask>^
    echo Exemple : od.bat *
    goto :Eof
)

rem
rem Setting the PATH environment variable for this batch file for accessing 7za.exe.
rem
path=c:\temp;%PATH%

rem
rem Removing quotes from the given command line parameter path.
rem
set root=%1
set root=%root:~%1
set root=%root:~0,-1%

rem Searching directory structure from root for subfolders and zipfiles, then extracting the zipfiles into a subfolder of the same name as the zipfile.
for /F "delims==" %%d in ('dir /ogne /ad /b /s %root%') do (
    echo Traitement du dossier : "%%d"

    for /F "delims==" %%f in ('dir /b "%%d\*.zip"') do (
        rem Getting filename without extension.
        set subfolder=~n%f
        mkdir "%%d\%subfolder%"
        rem Extracting zipfile content to the newly created folder.
        7za.exe e "%%d\%%f" -o"%%d\%subfolder%"
    )
)

:Eof

endlocal

我遇到的唯一麻烦是,它想要创建(按照我的示例)File5子文件夹,以便将 zip 文件提取到其中。提取实际File5.zip文件时这没有问题。但是,当它在目录结构中深入挖掘到子文件夹时,由于它已经获得了最后一个File5文件名,因此它想要在中创建 File5 子文件夹Folder 1\Folder A,例如,提取File1.zip。以下是结构示例:


║═════ Folder 1
║         ║
║         ║══════ Folder A
║                     ║
║                     ║═════ File1.zip
║═════ Folder 5
          ║═════ File5.zip

因此,考虑到上面说明的结构,它想要File5在 中创建Folder A,而它应该打算在 中创建File1

感谢您的支持和帮助!=)

任何人的帮助都将不胜感激。

编辑#5

我接受了@Dennis Williamson 的答案,因为他的解决方案满足了我首先提出的问题。否则,如果您正在寻找完全递归的解决方案,请按照我自己的答案中提供的链接操作,该链接将带您进入 StackOverflow 网站。

答案1

您可以使用PUSHDPOPD

@echo off
set rootFolderCmdLnParam=%1
FOR /D %%d IN (%rootFolderCmdLnParam%\*) DO pushd %%d & (FOR %%z IN (*.zip) DO 7za.exe e "%%z") & popd 

像这样调用:

BatchScript.bat "c:\temp\usd\Folder 0"

答案2

这是一个 Windows .CMD 脚本,可能会对您有点帮助。

这不是一个完整的解决方案,但我希望你至少能从中获得一些想法。

REM @echo off
setlocal enableextensions enabledelayedexpansion

  if /I "%1" EQU "" (
    echo Syntax: %0 ^<directory-mask^>
    echo Example:  %0 *
    goto :EOF
  )

  for /D %%a in (%1) do call :ProcessFolder "%%a"
  goto :EOF

:ProcessFolder
  rem Changing working directory to '%1'. See 'HELP PUSHD'
  pushd "%1"
  for %%b in (*.zip) do call :ProcessFile "%%b"
  popd
  goto :EOF

:ProcessFile
  rem Extract only filename-without-extension from %1 argument. See 'HELP FOR'
  set SUBFLDR=%~n1

  mkdir "%SUBFLDR%"
  pushd "%SUBFLDR%"

  echo Put processing here, like   7za.exe e "%1"

  popd
  goto :EOF

答案3

您还可以使用 FORFILES.EXE 和 /S 开关。这也在资源工具包中。

答案4

以下链接中@aphoria 提供的答案允许脚本完全递归,以创建与 zip 文件同名的子文件夹等。

以下是 StackOverflow 上对同一问题的答案的链接

谢谢大家,你们给了我很大的帮助。

相关内容