中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-08-02 05:56
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » 求助:正则表达式批量修改文件名(高手帮我) 查看 4,025 回复 17
楼 主 求助:正则表达式批量修改文件名(高手帮我) 发表于 2006-09-27 07:17 ·  中国 上海 闵行区 电信
初级用户
积分 34
发帖 11
注册 2006-09-16 22:47
19年会员
UID 62796
来自 上海
状态 离线
如 c:\movie 文件夹下,有许多rmvb格式的电影文件,命名很复杂,如 cb***01***.rmvb,cb**02****.rmvb,dd****03*.rmvb等。 如何一次批量修改以cb开头的文件,再用正则表达式取到中间的数字字段,使新的名称为: cb_01.rmvb,cb_02.rmvb,cb_03.rmvb 呢?
谢谢!!
2 发表于 2006-09-27 09:21 ·  中国 广东 佛山 广东睿江科技有限公司
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
  如果命名很复杂而又没什么规律可寻的话,光凭正则表达式来探测数字的字段,是非常不容易的。请把文件名的组成规律说的再详细一点。
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
3 发表于 2006-09-27 09:29 ·  中国 甘肃 张掖 电信
金牌会员
★★★★
积分 4,103
发帖 1,744
注册 2006-01-20 13:00
20年会员
UID 49241
性别 男
来自 甘肃.临泽
状态 离线
我看是行的通的,因为命名是没有规律的
4 发表于 2006-09-28 00:04 ·  中国 北京 朝阳区 联通
金牌会员
★★★★
积分 2,902
发帖 1,147
注册 2006-09-21 12:00
19年会员
UID 63324
性别 男
状态 离线
最好把那些文件名重定向到一个文件,传上来大家看看~:)
5 发表于 2006-09-28 04:24 ·  中国 江苏 苏州 电信
银牌会员
★★★
积分 1,181
发帖 533
注册 2006-08-14 12:54
19年会员
UID 60484
状态 离线

@echo off
setlocal ENABLEDELAYEDEXPANSION
set /a varrepeat=1
for /f %%i in ('dir/b cb*.rmvb') do (
call :GETNUM %%i
if not !number!==# (
ren %%i cb_!number!.rmvb 2>nul && echo %%i =^> cb_!number!.rmvb || ( ren %%i cb_!number!^(!varrepeat!^).rmvb 2>nul && set /a varrepeat=!varrepeat!+1 && echo %%i =^> cb_!number!.rmvb 目标已经存在 && echo %%i =^> cb_!number!^(!varrepeat!^).rmvb )
)
)
echo.
echo 处理完毕,按任意键结束。
pause>nul
GOTO END

:GETNUM
set varstr=%1#
set number=#
:LOOP
if !varstr!==# GOTO ENDLOOP
set firstchar=!varstr:~0,1!
if !firstchar! GEQ 0 (
if !firstchar! LEQ 9 (
set number=!number!!firstchar!
)
)
set varstr=!varstr:~1!
GOTO LOOP
:ENDLOOP
if not !number!==# set number=!number:~1!
:END


[ Last edited by NaturalJ0 on 2006-9-28 at 05:08 ]
6 发表于 2006-09-28 04:59 ·  中国 广东 佛山 广东睿江科技有限公司
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
  NaturalJ0 的代码通过探测文件名的每一个字符,只提取其中的数字的方法达到了对含有数字的文件名进行改名的目的,是个通行方案,非常不错。

[ Last edited by namejm on 2006-9-28 at 05:02 ]
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
7 发表于 2006-09-28 10:05 ·  中国 上海 闵行区 电信
初级用户
积分 34
发帖 11
注册 2006-09-16 22:47
19年会员
UID 62796
来自 上海
状态 离线
五楼的 NaturalJ0
伟人! 太佩服了! 五体投地!
我决定先把代码读懂了,再去试试先!
8 发表于 2006-09-28 22:40 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
5楼的代码写得不错, 但我电脑上执行未成功, 我也用一个新的思路写了一段, 相信更能符合楼主的要求.

代码的执行原理是: 查找c:\movie目录下文件名为cb***01***.rmvb类似格式的文件. 提取其中的数字也就是01等, 并将该文件重命名为cb_01.rmvb的格式.

这就达到了文件名中数字不变, 只改变其格式的目的. 但会过滤掉除阿拉伯数字外的所有字符(如果要保留其他字符或字符串, 请在FOR语句中添加).

另外, 脚本会生成日志文件, 记录处理与未处理的文件总数, 并把未处理的文件写入文件列表. 这样整个代码的执行情况就一目了然了.

稍微修改其中的代码就可以重命名任何文件夹下各种类型的文件. 但是必须符合一定规律.

代码虽然经过测试未发现问题, 但也难免会出现错误, 请谨慎使用!

@echo off
:: 本段代码为重命名c:\movie目录下文件名为(cb*数字.rmvb)的文件.
::
:: 重命名的规律是提取匹配的.rmvb文件中的数字, 然后把提取到的数字给文件取名为cb_数字.rmvb的格式.
::
:: 注意! 只提取匹配文件中的数字, 其他字符将被过滤. 如果文件名不存在数字将不做处理.
::
:: 请慎用此段代码!
set /a how=0
set /a how_=0
setlocal enabledelayedexpansion
for /f "tokens=*" %%i in ('dir /a-d /b "c:\movie\cb*.rmvb"') do (
set filename=%%i
set filename_=!filename:~0,-5!:
set name=
call :go
)
(
echo ========================
echo.
echo 共处理文件个数:!how!
echo.
echo 未处理文件个数:!how_!
echo.
echo ========================
)>>unsettled.txt
cls
echo 所有rmvb类型的文件已处理完毕, 请查看日志.
echo.
pause
start unsettled.txt
exit

:go
set num=!filename_:~0,1!
if not "!num!"==":" (
set term=
for %%a in (0 1 2 3 4 5 6 7 8 9) do (
if "!num!"=="%%a" (
set filename_=!filename_:~1!
set name=!name!%%a
set term=
goto go
)
)
if "!term!"=="" set filename_=!filename_:~1!
goto go
)
if not "!name!"=="" (
if exist "c:\movie\cb_!name!.rmvb" (
cls
echo cb_!name!.rmvb文件已存在, 没执行重命名. 系统会将未做处理的文件生成日志unsettled.txt
echo c:\movie\!filename!>>unsettled.txt
set /a how_+=1
pause
) else (
ren "c:\movie\!filename!" cb_!name!.rmvb
set /a how+=1
)
)
goto :eof


本段代码具有更大的灵活性, 楼主可以在FOR语句中加入需要匹配的字符或字符串, 这样在重命名文件时这些字符都将保留下来.

[ Last edited by pengfei on 2006-9-28 at 23:35 ]
9 发表于 2006-09-28 22:44 ·  中国 甘肃 张掖 电信
金牌会员
★★★★
积分 4,103
发帖 1,744
注册 2006-01-20 13:00
20年会员
UID 49241
性别 男
来自 甘肃.临泽
状态 离线
要是楼主所说的文件名中有 cb*0*01***.rmvb,这样的文件名那?
10 发表于 2006-09-28 22:47 ·  中国 江苏 苏州 电信
银牌会员
★★★
积分 1,181
发帖 533
注册 2006-08-14 12:54
19年会员
UID 60484
状态 离线
我写的那段不能处理所有情况。比如原来目录中就含有 (1) 这种文件的话,部分文件就有可能改名失败。你说的未成功是指错在这里吗?

[ Last edited by NaturalJ0 on 2006-9-28 at 22:48 ]
11 发表于 2006-09-28 22:57 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
Originally posted by he200377 at 2006-9-28 22:44:
要是楼主所说的文件名中有 cb*0*01***.rmvb,这样的文件名那?


如果是这样的文件名将会生命名为 cd_001.rmvb.

有可能出现重复, 但以后的出现提取到001这样的字符, 程序将会不作任何处理, 将未处理的文件写入文件列表.

不过以楼主的文件名规律来看, 应该可以正确处理所有文件. 将会重命名为cd_01.rmvb, cd_02.rmvb..., cd_n.rmvb
12 发表于 2006-09-28 22:59 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
Originally posted by NaturalJ0 at 2006-9-28 22:47:
我写的那段不能处理所有情况。比如原来目录中就含有 (1) 这种文件的话,部分文件就有可能改名失败。你说的未成功是指错在这里吗?

[ Last edited ...


我只是试运行了一下, 没有任何反应. 文件夹下的文件名为 cd-----01----.rmvb, cd-----02----.rmvb, cd-----03----.rmvb......
13 发表于 2006-09-28 23:07 ·  中国 江苏 苏州 电信
银牌会员
★★★
积分 1,181
发帖 533
注册 2006-08-14 12:54
19年会员
UID 60484
状态 离线
的确不能成功,因为我处理的是 CB 开头的文件,你的是 CD 开头的文件。
14 发表于 2006-09-28 23:09 ·  中国 湖南 娄底 电信
银牌会员
★★★
积分 1,218
发帖 485
注册 2006-07-21 21:24
20年会员
UID 58987
来自 湖南.娄底
状态 离线
原来是我看错了, 那我那段代码也应该改成cb了...
15 发表于 2006-09-30 06:57 ·  中国 上海 杨浦区 电信
初级用户
积分 34
发帖 11
注册 2006-09-16 22:47
19年会员
UID 62796
来自 上海
状态 离线
多谢各位大哥,我是个新手,只看过一些肤浅的教材,看你们的代码发现有以下不明白的地方,请耐心教导,谢谢!
if not !number!==# ::这里的#是什么意思?
=^> ::什么意思?
if !firstchar! GEQ 0 ::GEO什么意思 还有LSS什么意思?
非常感谢这个论坛!如果觉得问得愚昧,先把我骂一遍再解答吧,^_^ ^_^
论坛跳转: