假设有以下目录结构:
\
└─SomeRootFolder
├─SuperfolderA
│ ├─filenames.txt
│ ├─passwords.txt
│ ├─A1
│ │ └─...
│ ├─A2
│ │ └─...
│ └─...
├─SuperfolderB
│ ├─filenames.txt
│ ├─passwords.txt
│ ├─B1
│ │ └─...
│ ├─B2
│ │ └─...
│ └─...
└─...
(子文件夹A1
,A2
,... B1
,B2
等需要放入它们自己的归档文件中),以下对我有用:
@ECHO OFF
SET arch="C:\Program Files (x86)\WinRAR\WinRAR.exe"
SET "rootdir=D:\path\to\folders"
SET "namestxt=filenames.txt"
SET "passtxt=passwords.txt"
FOR /D %%D IN ("%rootdir%\*") DO (
<"%%D\%passtxt%" (
FOR /F "usebackq delims=" %%N IN ("%%D\%namestxt%") DO (
SET /P "pass="
SETLOCAL EnableDelayedExpansion
%arch% a -r -ep1 -hp!pass! "%%D\%%N.rar" "%%D\%%N"
ENDLOCAL
)
)
)
首先,该部分仅设置一些变量,稍后在脚本中使用。(恰好每个变量在脚本中仅使用一次,因此可以轻松地将值替换为相应的变量展开。我只是习惯性地声明这些变量,在我的批处理脚本中经常使用这样的变量。)
外部循环(即FOR /D)遍历您的“超级文件夹”,其中包含要归档的子文件夹和文本文件。
该循环的内容以以下方式读取两个文件:
1. filenames.txt由内部循环指令本身(for /f命令)读取;
2. 密码文件由内部循环体中的一个命令(read)读取。SET / P读取标准输入流,其默认情况下为控制台,但在这种情况下,整个内部循环的标准输入会被重定向为passwords.txt。
因此,%%D循环变量(外部循环)包含到“超级文件夹”的完整路径,%%N分配了子文件夹的名称,而pass则设置为相应的密码。此时,只需调用压缩程序即可。
以下是压缩程序命令行中使用的参数:
- a - 添加命令本身(与提取等命令不同,提取是x,更新是u);
- -r - 递归处理指定的文件夹(如果您不需要,可以删除此选项);
- -ep - 从名称中排除基本文件夹;
- -hp... - 使用指定的密码加密归档文件(与-p...不同,后者仅保护提取; -hp将不允许您在没有密码的情况下查看归档内容,就像您想要的那样)。
您可以看到,在调用压缩程序之前启用了延迟扩展。如果您不了解命令块(其中包括循环体)中“立即”扩展的影响,我只是说,如果变量在分配和扩展同一命令块中,则其不会按照您的期望工作。因此使用延迟扩展。它使用!s而不是% s,并且您可以看到pass变量以这种方式扩展。
还有一件事情需要提到。如果你生成的密码数量少于另一个文件中的名称数量,脚本仍然可以正常工作,但是缺少“自己”的密码的名称将与列表中的最后一个密码配对。(如果
名称少于密码也不是问题。在这种情况下,“孤立”的密码就不会被使用。)
更新
如果您想直接从目录中读取子文件夹名称,而放弃使用filenames.txt
文件,则可以像这样更改脚本:
@ECHO OFF
SET arch="C:\Program Files (x86)\WinRAR\WinRAR.exe"
SET "rootdir=D:\path\to\folders"
SET "namestxt=filenames.txt"
SET "passtxt=passwords.txt"
FOR /D %%D IN ("%rootdir%\*") DO (
<"%%D\%passtxt%" (
FOR /D %%N IN ("%%D\*") DO (
SET /P "pass="
SETLOCAL EnableDelayedExpansion
%arch% a -m0 -r -ep1 -hp!pass! "%%N.rar" "%%N"
ENDLOCAL
)
)
)
更新2
如果你想动态生成filenames.txt
文件,从目录中读取名称,只需在第一个脚本的外循环中插入一个命令:
@ECHO OFF
SET arch="C:\Program Files (x86)\WinRAR\WinRAR.exe"
SET "rootdir=D:\path\to\folders"
SET "namestxt=filenames.txt"
SET "passtxt=passwords.txt"
FOR /D %%D IN ("%rootdir%\*") DO (
DIR /AD /B "%%D" >"%%D\%namestxt%"
<"%%D\%passtxt%" (
FOR /F "usebackq delims=" %%N IN ("%%D\%namestxt%") DO (
SET /P "pass="
SETLOCAL EnableDelayedExpansion
%arch% a -r -ep1 -hp!pass! "%%D\%%N.rar" "%%D\%%N"
ENDLOCAL
)
)
)
/AD
switch是
DIR
命令的一个开关,它确保只包含文件夹名称。
请注意,您可以以类似的方式生成密码。如果有一种单个命令接受输出文件名作为参数,并且在没有中断的情况下完成工作,您可以在
DIR
之后插入该命令。