RAR 在压缩包中使用相对路径 (Windows 版)

本文最后更新于:2022年4月8日 凌晨

缘起:我需要备份博客源文件

我想把我的博客(以下简称 本博 )的源文件打包压缩备份到本地。

所以,我用 RAR.exe 将博客源文件所在的文件夹 C:\Users\Kukmoon\kukmoon_blog\ 打包[1]

RAR u -r %TEMP%\kukmoon_blog.rar C:\Users\Kukmoon\kukmoon_blog\

但是,我发现,RAR 把绝对路径也放进了压缩包。这个压缩包打开以后,上来第一层是 Users 文件夹,第二层是 Kukmoon 文件夹,第三层是 kukmoon_blog 文件夹,到第四层才是所有的博客源文件。如动画 1 所示。

动画 1:压缩包里的绝对路径

怎样才能让 RAR.exe 在压缩包里使用相对路径呢?我的要求是,打开压缩包,第一层就是 kukmoon_blog 文件夹,如动画 2 所示。

动画 2:压缩包里的相对路径

RAR 的 -ep1 开关

经过摸索,我在 RAR 控制台版本的用户手册 (C:\Program Files\WinRAR\Rar.txt) 里找到了一个 -ep1 开关。这个开关可以在压缩包内去掉上一层文件夹,相当于使用相对路径,可搭配 RAR 的 au 命令使用。

官方对这个开关的解释是:

-ep1    Exclude base dir from names. Do not store the path entered
        in the command line.

        Example:

        all files and directories from the directory tmp will be added
        to the archive 'test', but the path in archived names will not
        include 'tmp\'

        rar a -ep1 -r test tmp\*

        This is equivalent to the commands:

        cd tmp
        rar a -r ..\test
        cd ..

例题精讲

下面我们用四道例题来解释 -ep1 参数的用法。

假设:在 C:\abc\def 文件夹下有个 1.txt 文件,有个 ghi 子文件夹,在这个子文件夹下有 2.txt 文件。

C:\
│  
├─abc
│  └─def
│      │  1.txt
│      │  
│      └─ghi
│              2.txt
               

【例 1】

执行命令:

RAR a -r example1.rar C:\abc\def

生成的 example1.rar 的内部结构是:

example1.rar
└─abc
    └─def
        │  1.txt
        │  
        └─ghi
                2.txt
                

显然,如果不使用 -ep1参数,并且压缩文件里包含了每个文件和文件夹的全部路径,从根目录开始算。

【例 2】

执行命令:

RAR a -r example2.rar C:\abc\def\

生成的 example2.rar 的内部结构是:

example2.rar
└─abc
    └─def
        │  1.txt
        │  
        └─ghi
                2.txt
                

例 2 和例 1 的区别在于,例 2 在输入列表文件(即待压缩的文件)的路径时,在 def 后面多加了一个反斜杠。加这个反斜杠的目的的指明 def 不是文件,而是子文件夹。

但是,生成的 example1.rarexamle2.rar 没有区别。

这说明,如果不加 -ep1 开关,那么在子文件夹的名称后面加不加斜杠,没有区别。

【例 3】

执行命令:

RAR a -r -ep1 example3.rar C:\abc\def

生成的 example3.rar 的内部结构是:

example3.rar
├─def
│  │  1.txt
│  │  
│  └─ghi
│          2.txt
        

例 3 和例 1 的区别在于,例 3 加入了 -ep1 开关。结果就是,abc 文件夹从压缩包里消失了,压缩包第一层文件结构是原来的 abc 目录里的 def 子文件夹。

为什么呢?

官方对这个 -ep1 参数的解释有一句话:

Exclude base dir from names.

其中,base dir 是上一层文件夹,例如,C:\abc\def\1.txt 的 base dir 是 ``C:\abc\def` 文件夹。

所以,例 3 这条命令 RAR a -r -ep1 example3.rar C:\abc\def 的作用是,从压缩包里排除 C:\abc\ 这个路径,压缩包的第一层结构是 def 子文件夹。

注意:如果在 C:\abc\ 文件夹中还有其它文件或文件夹,RAR 也会一起把它们排除,只保留 def 子文件夹。

【例 4】

执行命令:

RAR a -r -ep1 example4.rar C:\abc\def\

生成的 example4.rar 的内部结构是:

example4.rar
│  1.txt
│  
└─ghi
        2.txt

例 4 和 例 3 的区别是,例 4 在输入列表文件(即待压缩的文件)的路径时,在 def 后面多加了一个反斜杠。加这个反斜杠的目的的指明 def 不是文件,而是子文件夹。

结果是,exampl4.rar 不但排除了 abc 文件夹,连 def 文件夹也排除了。上来第一层文件夹结构是原来 def 文件夹中的 1.txtghi 子文件夹。

这是为什么呢?

计算机基础知识告诉我们,文件夹也是个特殊的文件,需要在文件夹名后面加个斜杠(Unix-like 操作系统要求用正斜杠,DOS/Windows 要求用反斜杠)作为标记。

如果不加斜杠,大多数情况下,系统会自动区分,但是个别情况下,区分无效,用户需要强行用斜杠表示区分。

这就属于那种需要用户自己加斜杠来区分的类型:

  • 如果不加斜杠,比如 C:\abc\def,系统把 def 当作文件名而不是文件夹名,所以,base dir 是 C:\abc\ 文件夹。
  • 如果加了斜杠,比如 C:\abc\def\,系统把 def\ 当作文件夹名,那么 base dir 就是 C:\abc\def\ 文件夹。

我甚至怀疑,RAR.exe 的源代码是这么写的:从右向左寻找第一个斜杠,把第一个斜杠左边的字符串作为 base dir,从而把它对应的文件夹路径从压缩包里排除出去。

【例 5】

执行命令:

RAR a -r -ep1 example5.rar C:\abc\def\*

生成的 example5.rar 的内部结构,与 example4.rar 一样:

example5.rar
│  1.txt
│  
└─ghi
        2.txt

注意事项

  1. 无论是不是加 -ep1 开关,RAR 都会把 C:\C:\abc\ 中的其它内容(包括文件、子文件夹、子文件夹中的文件)排除掉,只保留 C:\abc\def\ 文件夹下的内容。

  2. 7z 默认排除 base dir,不用问 7z 用什么开关才能排除 base dir。

参考文献