Packing (WinRAR) with a password on a group of files

▼魔方 西西 提交于 2019-12-01 18:31:24

Assuming this directory structure:

\
└─SomeRootFolder
  ├─SuperfolderA
  │ ├─filenames.txt
  │ ├─passwords.txt
  │ ├─A1
  │ │ └─...
  │ ├─A2
  │ │ └─...
  │ └─...
  ├─SuperfolderB
  │ ├─filenames.txt
  │ ├─passwords.txt
  │ ├─B1
  │ │ └─...
  │ ├─B2
  │ │ └─...
  │ └─...
  └─...

(the subfolders A1, A2, ... B1, B2, ... being the ones that need be put into their own archives), the following worked for me:

@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
    )
  )
)

The first part merely sets up some variables, used later in the script. (As it happens, every one of them is used in the script just once, so you could easily substitute the values for the corresponding variable expansions. I only declared those variables habitually, I often use variables like that in my batch scripts.)

The outer loop, the FOR /D one, iterates over your ‘superfolders’, those containing subfolders to archive and the text files.

The loop's body reads two files in this way:

  • the filenames.txt is read by the inner loop instruction itself, the FOR /F command;

  • the password file is read by one of the commands in the inner loop's body, namely SET /P. SET /P reads the standard input stream, which is the console by default, but the standard input in this case is redirected for the entire inner loop to be from the passwords.txt instead.

So, the %%D loop variable (the outer loop's one) contains the complete path to a ‘superfolder’, %%N is assigned a subfolder's name and pass= is set to a corresponding password. It only remains at this point to call the archiver.

These the parameters used in the archiver command line:

  • a – the Add command proper (as opposed to commands like Extract, which is x, or Update, which is u);

  • -r – process the specified folder recursively (if you don't need that, remove this option);

  • -ep – exclude the base folder from names;

  • -hp… – encrypt the archive with the specified password (which is different from -p…, which merely protects the extraction; -hp won't let you see the contents of the archive without the password, just like you seem to want).

You can see that before calling the archiver, the delayed expansion is enabled. If you aren't aware of the effects of ‘immediate’ expansion in bracketed blocks of commands (which includes loop bodies), I'll just say that it doesn't work like you want it if the variable is both assigned and expanded in the same bracketed block. Hence delayed expansion. It uses !s instead of %s and you can see the pass variable expanded that way.

There's one more thing that needs to be mentioned. If you generate fewer passwords than there are names in the other file, the script will still work fine but the names lacking their ‘own’ passwords would be paired with the last password in the list. (It is also no problem for the script if names are fewer than the passwords. In this case, the ‘orphaned’ passwords just won't be used.)


UPDATE

If you would like to read subfolder names directly from the directory, thus abandoning the filenames.txt files, you could change the script like this:

@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
    )
  )
)

UPDATE 2

If you want to generate filenames.txt files on the fly reading the names from the directory, insert just one command into the first script's outer loop:

@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
    )
  )
)

The /AD switch of DIR makes sure only folder names are included.

Note that you could generate the passwords in a similar way. If there's a single command that accepts the output file name as a parameter and just does the job without interruptions, you could insert that command just after the DIR.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!