这些规则是在Vista机器上进行大量测试后发现的。没有对文件名中的Unicode执行任何测试。
RENAME需要2个参数-sourceMask,然后是targetMask。sourceMask和targetMask都可以包含*
和/或?
通配符。在源掩码和目标掩码之间,通配符的行为略有不同。
注 - REN可用来重命名文件夹,但通配符不能重命名的文件夹时,无论是在sourceMask或targetMask允许的。如果sourceMask至少匹配一个文件,则文件将被重命名并且文件夹将被忽略。如果sourceMask仅匹配文件夹而不匹配文件,则如果在源或目标中出现通配符,则会生成语法错误。如果sourceMask不匹配任何内容,则将导致“找不到文件”错误。
另外,重命名文件时,只能在sourceMask的文件名部分使用通配符。指向文件名的路径中不允许使用通配符。
sourceMask
sourceMask用作确定重命名哪些文件的过滤器。通配符在这里的工作方式与任何其他过滤文件名的命令相同。
所有非通配符必须匹配自己,除了一些特殊情况例外。
.
-匹配自身,或者如果没有更多字符,则可以匹配名称的末尾(无)。(注意-有效的Windows名称不能以结尾.
)
{space}
-匹配自身,或者如果没有更多字符,则可以匹配名称的末尾(无)。(注意-有效的Windows名称不能以结尾{space}
)
*.
在结束-匹配任何0或更多字符,除了 .
端接.
实际上可以任意组合.
,并{space}
只要在面具的最后一个字符是.
这是一个和唯一的例外,*
不是简单地匹配任何字符集。
上面的规则并不那么复杂。但是还有一个更重要的规则使情况令人困惑:将SourceMask与长名称和短8.3名称(如果存在)进行比较。这最后一个规则会使结果的解释非常棘手,因为当掩码通过短名称匹配时,它并不总是显而易见的。
可以使用RegEdit禁用NTFS卷上短8.3名称的生成,这时文件掩码结果的解释更为直接。禁用短名称之前生成的任何短名称都将保留。
targetMask
注意-我尚未进行任何严格的测试,但看来这些相同的规则也适用于COPY命令的目标名称
targetMask指定新名称。它总是应用于全名;即使sourceMask与8.3的短名称匹配,也不会将targetMask应用于8.3的短名称。
sourceMask中是否存在通配符对targetMask中的通配符处理方式没有影响。
在下面的讨论- c
代表任意字符,是不是*
,?
或.
严格按照从左到右的顺序对源名称进行targetMask处理,没有回溯。
c
-只要不是下一个字符,就在源名称中提升位置.
,并将其追加c
到目标名称之后。(用替换源中的字符c
,但从不替换.
)
?
-匹配从源长名称下一个字符,只要下一个字符不是其附加到目标名称.
如果下一个字符是.
,或者如果在源名称的末尾则没有字符被添加到结果和当前源名称中的位置保持不变。
*
在targetMask的末尾-将所有剩余的字符从源追加到目标。如果已经在源末尾,则不执行任何操作。
*c
-匹配从当前位置到最后一次出现的所有源字符c
(区分大小写的贪婪匹配),并将匹配的字符集附加到目标名称。如果c
未找到,则将附加源中所有剩余的字符,然后单击“添加”。c
这是我知道的唯一情况,Windows文件模式匹配区分大小写。
*.
-通过从匹配的当前位置的所有源字符最后的次数.
(贪婪匹配)和附加字符的匹配组的目标名称。如果.
未找到,则将附加源中的所有剩余字符,后跟.
*?
-将所有剩余的字符从源追加到目标。如果已经在源的末尾,则不执行任何操作。
.
不*
位于最前面-在第一次出现时使源代码中的位置前进,.
而不复制任何字符,并追加.
到目标名称。如果.
在源中找不到,则前进到源末尾并追加.
到目标名称。
该targetMask已经用尽之后,任何尾随.
而{space}
被修剪掉所产生的目标名称的末尾,因为Windows文件名不能结束.
或{space}
一些实际的例子
在任何扩展名之前将字符替换为第一和第三位置(如果尚不存在,则添加第二或第三字符)
ren * A?Z*
1 -> AZ
12 -> A2Z
1.txt -> AZ.txt
12.txt -> A2Z.txt
123 -> A2Z
123.txt -> A2Z.txt
1234 -> A2Z4
1234.txt -> A2Z4.txt
更改每个文件的(最终)扩展名
ren * *.txt
a -> a.txt
b.dat -> b.txt
c.x.y -> c.x.txt
将扩展名附加到每个文件
ren * *?.bak
a -> a.bak
b.dat -> b.dat.bak
c.x.y -> c.x.y.bak
在初始扩展名之后删除所有多余的扩展名。请注意,?
必须使用足够的名称来保留现有的完整名称和初始扩展名。
ren * ?????.?????
a -> a
a.b -> a.b
a.b.c -> a.b
part1.part2.part3 -> part1.part2
123456.123456.123456 -> 12345.12345 (note truncated name and extension because not enough `?` were used)
与上述相同,但过滤掉名称和/或扩展名超过5个字符的文件,以使它们不会被截断。(显然可以?
在targetMask的任一端添加一个附加名称,以保留名称和扩展名,最长为6个字符)
ren ?????.?????.* ?????.?????
a -> a
a.b -> a.b
a.b.c -> a.b
part1.part2.part3 -> part1.part2
123456.123456.123456 (Not renamed because doesn't match sourceMask)
更改_
名称中姓氏后面的字符,并尝试保留扩展名。(如果_
出现在扩展名中,则无法正常工作)
ren *_* *_NEW.*
abcd_12345.txt -> abcd_NEW.txt
abc_newt_1.dat -> abc_newt_NEW.dat
abcdef.jpg (Not renamed because doesn't match sourceMask)
abcd_123.a_b -> abcd_123.a_NEW (not desired, but no simple RENAME form will work in this case)
可以将任何名称分解成用.
字符分隔的组件,只能在每个组件的末尾附加或删除。在使用通配符保留其余字符时,不能从组件的开头或中间删除字符或将其添加到组件的开头或中间。允许在任何地方替换。
ren ??????.??????.?????? ?x.????999.*rForTheCourse
part1.part2 -> px.part999.rForTheCourse
part1.part2.part3 -> px.part999.parForTheCourse
part1.part2.part3.part4 (Not renamed because doesn't match sourceMask)
a.b.c -> ax.b999.crForTheCourse
a.b.CarPart3BEER -> ax.b999.CarParForTheCourse
如果启用了短名称,则名称至少为8 ?
且?
扩展名为至少3 的sourceMask 将与所有文件匹配,因为它始终与8.3短名称匹配。
ren ????????.??? ?x.????999.*rForTheCourse
part1.part2.part3.part4 -> px.part999.part3.parForTheCourse
有用的怪癖/错误?用于删除名称前缀
这篇SuperUser帖子介绍了如何使用一组正斜杠(/
)从文件名中删除前导字符。每个要删除的字符都需要一个斜杠。我已确认Windows 10计算机上的行为。
ren "abc-*.txt" "////*.txt"
abc-123.txt --> 123.txt
abc-HelloWorld.txt --> HelloWorld.txt
仅当源掩码和目标掩码都用双引号引起来时,此技术才有效。以下所有不带必需引号的表格均会因该错误而失败:The syntax of the command is incorrect
REM - All of these forms fail with a syntax error.
ren abc-*.txt "////*.txt"
ren "abc-*.txt" ////*.txt
ren abc-*.txt ////*.txt
该/
不能被用于去除在一个文件名称的中间或端部的任何字符。它只能删除前导(前缀)字符。
从技术上讲,/
不能用作通配符。而是执行简单的字符替换,但是替换后,REN命令识别/
出文件名中的无效字符,并/
从名称中去除前导斜杠。如果REN /
在目标名称中间检测到,则会给出语法错误。
可能的RENAME错误-单个命令可能将同一文件重命名两次!
从一个空的测试文件夹开始:
C:\test>copy nul 123456789.123
1 file(s) copied.
C:\test>dir /x
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\test
09/15/2012 07:42 PM <DIR> .
09/15/2012 07:42 PM <DIR> ..
09/15/2012 07:42 PM 0 123456~1.123 123456789.123
1 File(s) 0 bytes
2 Dir(s) 327,237,562,368 bytes free
C:\test>ren *1* 2*3.?x
C:\test>dir /x
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\test
09/15/2012 07:42 PM <DIR> .
09/15/2012 07:42 PM <DIR> ..
09/15/2012 07:42 PM 0 223456~1.XX 223456789.123.xx
1 File(s) 0 bytes
2 Dir(s) 327,237,562,368 bytes free
REM Expected result = 223456789.123.x
我相信sourceMask *1*
首先匹配长文件名,并且文件被重命名为的预期结果223456789.123.x
。然后,重命名继续寻找要处理的更多文件,并通过新的短名称来找到新命名的文件223456~1.X
。然后再次重命名该文件,得到的最终结果223456789.123.xx
。
如果禁用8.3名称生成,则RENAME会提供预期的结果。
我还没有完全弄清楚引发这种奇怪行为的所有触发条件。我担心可能会创建一个永无止境的递归RENAME,但是我从来没有能够诱导一个。
我相信以下所有内容都必须正确才能引发该错误。我看到的每个错误案例都有以下条件,但并非所有满足以下条件的案例都存在错误。
- 短的8.3名称必须启用
- sourceMask必须与原始长名称匹配。
- 初始重命名必须生成一个短名称,该短名称也必须与sourceMask相匹配
- 初始重命名的短名称的排序必须晚于原始短名称(如果存在)?