批量将扩展名重命名为小写
Batch rename extension to lowercase
我可以使用
将包含 .TXT 文件的文件夹重命名为小写扩展名
ren *.TXT *.txt
但那是因为我知道扩展名,只有一个。是否有一个用于遍历目录并将所有扩展名更改为小写的一行?
我试过了:
for %%f in (*.*) do (rename "%%f" "%%~xf")
这在某种程度上是有效的,但它也删除了文件名部分。哦!
更好地失败。
它是可以用纯批处理但笨拙。
为此,我建议使用包裹在 cmdline/batch 中的 PowerShell 脚本:
powershell -nop -c "gci -file|ren -newname {$_.BaseName+($_.Extension.ToLower())}"
只需在您的原始代码中再添加 两行:1. 获取扩展名。 2. 转为小写。
@echo off
setlocal EnableDelayedExpansion
for %%f in (*.*) do (
set "ext=%%~Xf"
for %%c in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set "ext=!ext:%%c=%%c!"
ren "%%f" "%%~Nf!ext!"
)
编辑: 下面的新方法可以正确处理文件没有扩展名的情况。这种方法也更有效,因为它只将一个字符串转换为小写字母,并对每个扩展名而不是每个文件执行 ren
命令。这些是步骤: 1. 在字符串中获取所有 不同的 文件扩展名。 2. 将此字符串转换为小写。 3. 使用此字符串中的每个扩展名执行 ren
命令。
@echo off
setlocal EnableDelayedExpansion
set "exts= "
for %%f in (*.*) do if "!exts:%%~Xf=!" equ "!exts!" set "exts=!exts! %%~Xf"
for %%c in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set "exts=!exts:%%c=%%c!"
for %%e in (%exts%) do ren "*%%e" "*%%e"
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /f "delims=" %%A IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
FOR /f "delims=" %%a IN (
'dir /b /l "%sourcedir%\%%A" '
) DO (
if "%%~xa" neq "%%~xA" ECHO REN "%sourcedir%\%%A" "%%~nA%%~xa"
)
)
GOTO :EOF
当然,如果需要,两个嵌套的 for
命令可以压缩到一行 - 此处显示为多行以便于阅读。
您需要更改 sourcedir
的设置以适合您的情况。
所需的 REN 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO REN
更改为REN
以实际重命名文件。
请注意,%%A
保留原始字符大小写,但 %%a
(一个完全 不同的 变量)获取小写等价物,因为 /l
打开 dir
命令。
在 Aacini 的回应之后,更广泛的测试(好吧,实际上是尝试重命名文件,而不是仅仅生成乍一看 应该 工作的重命名指令)显示这实际上并不工作,可能是因为 OS 看到一个文件被重命名为它自己的名字(忽略大小写)。哼。
所以 - 第一步是重命名两次 - 首先是一个虚拟名称,然后从虚拟名称到所需的名称。
理论上没问题。问题是 ~x
运算符似乎并没有始终如一地报告相同的字符串——几乎取决于它被使用了多少次。所以 - 我尝试执行一个子例程,传递 "to" 和 "from" 文件名。尝试访问参数的名称片段时,子例程似乎也有同样的问题。忧郁.
所以我将名称分配给一个变量并尝试处理 that。重复删除名称中 .
之前的字符串,直到没有更多的点并且您有扩展名。
然后从文件名中删除扩展名,但不能使用替换为空的方法,因为文件名可能是 whatever.txt.txt
。因此,在找到的扩展长度+1(对于点)的循环中一次一个地删除最后几个字符。
因此 - 如果找到的扩展的小写版本与 ext2
中的当前大小写版本相同,则不需要重命名。否则,重命名为原始名称+小写扩展名。通过虚拟名称确保 OS 不会变得太聪明。
这是结果。当然,使用常用字符可能会出现意想不到的结果。
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
:choosedummy
SET "dummyname=dummyname.%random%"
IF EXIST "%sourcedir%\%dummyname%" GOTO choosedummy
FOR /f "delims=" %%A IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
FOR /f "delims=" %%a IN (
'dir /b /l "%sourcedir%\%%A" '
) DO CALL :casechg "%%a" "%%A"
)
GOTO :EOF
:casechg
SET "ext2=%~2"
SET "name2=%~2"
:ext2loop
IF "%ext2%" neq "%ext2:*.=%" SET "ext2=%ext2:*.=%"&GOTO ext2loop
:: if extension cases are identical, or no extension, skip rename
IF "%~x1" equ "" GOTO :EOF
IF "%~x1" equ ".%ext2%" GOTO :EOF
SET "lop=%ext2%"
:loploop
SET "name2=%name2:~0,-1%"
IF DEFINED lop SET "lop=%lop:~1%"&GOTO loploop
REN "%sourcedir%\%~2" "%dummyname%"
REN "%sourcedir%\%dummyname%" "%name2%%~x1"
GOTO :eof
我可以使用
将包含 .TXT 文件的文件夹重命名为小写扩展名ren *.TXT *.txt
但那是因为我知道扩展名,只有一个。是否有一个用于遍历目录并将所有扩展名更改为小写的一行?
我试过了:
for %%f in (*.*) do (rename "%%f" "%%~xf")
这在某种程度上是有效的,但它也删除了文件名部分。哦!
更好地失败。
它是可以用纯批处理但笨拙。
为此,我建议使用包裹在 cmdline/batch 中的 PowerShell 脚本:
powershell -nop -c "gci -file|ren -newname {$_.BaseName+($_.Extension.ToLower())}"
只需在您的原始代码中再添加 两行:1. 获取扩展名。 2. 转为小写。
@echo off
setlocal EnableDelayedExpansion
for %%f in (*.*) do (
set "ext=%%~Xf"
for %%c in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set "ext=!ext:%%c=%%c!"
ren "%%f" "%%~Nf!ext!"
)
编辑: 下面的新方法可以正确处理文件没有扩展名的情况。这种方法也更有效,因为它只将一个字符串转换为小写字母,并对每个扩展名而不是每个文件执行 ren
命令。这些是步骤: 1. 在字符串中获取所有 不同的 文件扩展名。 2. 将此字符串转换为小写。 3. 使用此字符串中的每个扩展名执行 ren
命令。
@echo off
setlocal EnableDelayedExpansion
set "exts= "
for %%f in (*.*) do if "!exts:%%~Xf=!" equ "!exts!" set "exts=!exts! %%~Xf"
for %%c in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set "exts=!exts:%%c=%%c!"
for %%e in (%exts%) do ren "*%%e" "*%%e"
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /f "delims=" %%A IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
FOR /f "delims=" %%a IN (
'dir /b /l "%sourcedir%\%%A" '
) DO (
if "%%~xa" neq "%%~xA" ECHO REN "%sourcedir%\%%A" "%%~nA%%~xa"
)
)
GOTO :EOF
当然,如果需要,两个嵌套的 for
命令可以压缩到一行 - 此处显示为多行以便于阅读。
您需要更改 sourcedir
的设置以适合您的情况。
所需的 REN 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO REN
更改为REN
以实际重命名文件。
请注意,%%A
保留原始字符大小写,但 %%a
(一个完全 不同的 变量)获取小写等价物,因为 /l
打开 dir
命令。
在 Aacini 的回应之后,更广泛的测试(好吧,实际上是尝试重命名文件,而不是仅仅生成乍一看 应该 工作的重命名指令)显示这实际上并不工作,可能是因为 OS 看到一个文件被重命名为它自己的名字(忽略大小写)。哼。
所以 - 第一步是重命名两次 - 首先是一个虚拟名称,然后从虚拟名称到所需的名称。
理论上没问题。问题是 ~x
运算符似乎并没有始终如一地报告相同的字符串——几乎取决于它被使用了多少次。所以 - 我尝试执行一个子例程,传递 "to" 和 "from" 文件名。尝试访问参数的名称片段时,子例程似乎也有同样的问题。忧郁.
所以我将名称分配给一个变量并尝试处理 that。重复删除名称中 .
之前的字符串,直到没有更多的点并且您有扩展名。
然后从文件名中删除扩展名,但不能使用替换为空的方法,因为文件名可能是 whatever.txt.txt
。因此,在找到的扩展长度+1(对于点)的循环中一次一个地删除最后几个字符。
因此 - 如果找到的扩展的小写版本与 ext2
中的当前大小写版本相同,则不需要重命名。否则,重命名为原始名称+小写扩展名。通过虚拟名称确保 OS 不会变得太聪明。
这是结果。当然,使用常用字符可能会出现意想不到的结果。
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
:choosedummy
SET "dummyname=dummyname.%random%"
IF EXIST "%sourcedir%\%dummyname%" GOTO choosedummy
FOR /f "delims=" %%A IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
FOR /f "delims=" %%a IN (
'dir /b /l "%sourcedir%\%%A" '
) DO CALL :casechg "%%a" "%%A"
)
GOTO :EOF
:casechg
SET "ext2=%~2"
SET "name2=%~2"
:ext2loop
IF "%ext2%" neq "%ext2:*.=%" SET "ext2=%ext2:*.=%"&GOTO ext2loop
:: if extension cases are identical, or no extension, skip rename
IF "%~x1" equ "" GOTO :EOF
IF "%~x1" equ ".%ext2%" GOTO :EOF
SET "lop=%ext2%"
:loploop
SET "name2=%name2:~0,-1%"
IF DEFINED lop SET "lop=%lop:~1%"&GOTO loploop
REN "%sourcedir%\%~2" "%dummyname%"
REN "%sourcedir%\%dummyname%" "%name2%%~x1"
GOTO :eof