Board logo

标题: [文件操作] [已解决]如何批量的提取指定文件名中的特定字符串和数值格式来给文件重命名 [打印本页]

作者: xinjinjie    时间: 2017-4-12 22:02     标题: [已解决]如何批量的提取指定文件名中的特定字符串和数值格式来给文件重命名

本帖最后由 xinjinjie 于 2017-4-25 22:01 编辑

首先说明一下,已搜索多次,找到类似的帖子学习观摩,但是发现和我想要达到的效果都不太一样,所以才发新帖子来请教。

想要批量的将文件夹中的文件用文件名中的不连续字符串来给文件重命名,比如
文件名:[GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv和[GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].ass,
改名为:GRANBLUE FANTASY_01.mkv和GRANBLUE FANTASY_01.ass。

我设想的是,在BAT代码里指定原始文件名中含有的部分字符串,比如“GRANBLUE FANTASY”、“Arrow”,判断文件夹中有含有这个字符串的文件时获取一个指定格式的数值,取出这个数值来和前面指定的字符串一起组成新的文件名。
比如:[aaaaaaaa][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv,在代码里指定“GRANBLUE FANTASY”,“[??]”,最后改名为“GRANBLUE FANTASY_??.mkv”。
Arrow.S05E18.1080p.WEB-DL.DD5.1.H264-RARBG.mkv,在代码里指定“Arrow.S05”,“E??”,最后改名为“Arrow.S05_??.mkv”。
ass后缀名的文件用同样的方式来实现改名。

要实现这个效果,应该怎么来写BAT的代码呢?

借鉴ShowCode大大曾经给出的、解决另一个改文件名需求的代码,不完全符合这个需求,自己写了个没效果的代码,还请ShowCode大大和其他大大们指点
  1.    @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%i in ('dir /b /a-d *GRANBLUE FANTASY*') do (
  4.     set "f=100%%~ni"
  5.     set "f=!f:[%%i]=!"
  6.     ren GRANBLUE FANTASY_"!f!"
  7. )
复制代码
符合需求的代码在21楼
作者: taofan712    时间: 2017-4-12 23:07

  1. @echo off
  2. for %%a in (*.mkv) do (
  3.     for /f "tokens=1,2 delims=[]" %%b in ("%%~na") do (
  4.         ren "%%~a" "%%b_%%c%%~xa"
  5.         ren "%%~na.ass" "%%b_%%c.ass"
  6.     )
  7. )
  8. pause
复制代码

作者: pcl_test    时间: 2017-4-13 04:56

回复 2# taofan712

这种for遍历文件的方式配合ren重命名需注意坑
作者: xinjinjie    时间: 2017-4-13 12:22

回复 2# taofan712


   虽然不能完全看懂这个代码,不过通过自己的连蒙带猜,似乎是检查到是MKV后缀名的文件后,通过获取第一个“[]”内的字符串来重命名,具体怎么获取的数字部分没看懂,怎么获取的ass后缀名的文件和对ass文件重命名的方法也没看懂,不过这个不是重点想要说的。

因为实际使用中,有可能第一个“[]”内的字符串不是需要的新的文件名的字符串,比如:[aaaaaaaa][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv,或者Arrow.S05E18.1080p.WEB-DL.DD5.1.H264-RARBG.mkv。这些情况的原始文件名的话,估计用层主这个代码是改不出想要的结果的。

所以,我设想的是,在BAT代码里指定原始文件名中含有的部分字符串,比如“GRANBLUE FANTASY”、“Arrow”,判断文件夹中有含有这个字符串的文件时获取一个指定格式的数值,取出这个数值来和前面指定的字符串一起组成新的文件名。
比如:[aaaaaaaa][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv,在代码里指定“GRANBLUE FANTASY”,“[??]”,最后改名为“GRANBLUE FANTASY_??.mkv”。
Arrow.S05E18.1080p.WEB-DL.DD5.1.H264-RARBG.mkv,在代码里指定“Arrow.S05”,“E??”,最后改名为“Arrow.S05_??.mkv”。
ass后缀名的文件用同样的方式来实现改名。

要实现这个效果,应该怎么来写BAT的代码呢?
作者: taofan712    时间: 2017-4-13 15:06

回复 4# xinjinjie

你这是批量解决问题,怎么可能在代码里指定某个具体文件名的关键字呢?
我之前写的是针对你一楼列举的情况,取第一和第二个[]中的字符。
你后面补充的内容,情况都不一样,需要加很多判断,特别麻烦。建议你自己学一下for和set,自己根据实际情况来写。
【for】http://www.bathome.net/thread-2189-1-1.html
【set】http://bbs.bathome.net/thread-14927-1-1.html
【if】http://www.bathome.net/thread-2530-1-1.html
作者: xinjinjie    时间: 2017-4-13 20:20

回复 5# taofan712


    感谢您的指点,我找时间观摩学习。
另外,说明一下,类似需要判断文件名中是否存在某个关键字符串的功能,BAT代码应该是有的吧?比如*GRANBLUE FANTASY*。我想达到的效果就是在代码里写入一个类似*GRANBLUE FANTASY*的代码来判断,含有这个内容的才去取用“[??]”这个格式的数字,最后改名为GRANBLUE FANTASY_??.mkv
作者: ShowCode    时间: 2017-4-13 22:50

回复 6# xinjinjie


@echo off
for %%a in ("*GRANBLUE FANTASY*.mkv") do (
    for /f "tokens=1,2 delims=[]" %%b in ("%%~na") do (
        ren "%%~a" "%%b_%%c%%~xa"
        ren "%%~na.ass" "%%b_%%c.ass"
    )
)
pause
作者: xinjinjie    时间: 2017-4-14 11:03

回复 7# ShowCode


    感谢ShowCode大大的指点,今天白天没什么时间,晚上有空了再来尝试、测试、研究。
作者: xinjinjie    时间: 2017-4-14 20:36

回复 7# ShowCode


    已测试,没有达到效果,例如,原始文件名为:[FLsnow&SumiSora][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv
运行这个代码后,被改名为了:FLsnow&SumiSora_GRANBLUE FANTASY-The Animation.mkv。文件名基本一致、关键字内容一致的的ass文件则完全没有被改名,[FLsnow&SumiSora][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].chs.ass
作者: xinjinjie    时间: 2017-4-16 09:29

回复 7# ShowCode


    自己尝试着将代码改成下面的,没效果,估计是哪里没写对,期待指正。
  1. @echo off
  2. for %%a in ("*GRANBLUE FANTASY*.mkv") do (
  3.     for /f "tokens=1,2 delims=[]" %%b in ("%%~na") do (
  4.       ren "%%b_%%c%%~xa"
  5.     )
  6. )
复制代码

作者: ShowCode    时间: 2017-4-18 15:48

回复 9# xinjinjie


@echo off
for %%a in ("*GRANBLUE FANTASY*.mkv") do (
    for /f "tokens=1,2 delims=[]" %%b in ("%%~na") do (
        echo ren "%%~a" "%%b_%%c%%~xa"
        echo ren "%%~na.ass" "%%b_%%c.ass"
    )
)
pause
用 echo 命令观察一下就知道了,这个代码成功的前提是:视频文件名和字幕文件名相同。

[FLsnow&SumiSora][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv
[FLsnow&SumiSora][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].chs.ass
但是你这个例子里面两个文件名不一致,所以ass没能改名。

调整一下方法:
  1. @echo off
  2. for %%a in ("*GRANBLUE FANTASY*.mkv" "*GRANBLUE FANTASY*.ass") do (
  3.     for /f "tokens=1,2 delims=[]" %%b in ("%%~na") do (
  4.         echo ren "%%~a" "%%b_%%c%%~xa"
  5.     )
  6. )
  7. pause
复制代码

作者: xinjinjie    时间: 2017-4-18 20:13

回复 11# ShowCode


    感谢ShowCode大大指点,刚才测试代码部分的新代码,结果还是没效果。

不过在CMD界面看到,好像获取到的新文件名有问题,显示在CMD界面的新文件名是“FLsnow&SumiSora_GRANBLUE FANTASY-The Animation.mkv”,没有了集数,01的MKV和02的MKV都是显示这个同样的新文件名,推测是因为这个原因改名没效果。另外两个的ass文件也是同样的,没有了集数、没改名成功。
作者: ShowCode    时间: 2017-4-18 22:27

回复 12# xinjinjie


@echo off
for %%a in ("*GRANBLUE FANTASY*.mkv" "*GRANBLUE FANTASY*.ass") do (
    for /f "tokens=1,2,3 delims=[]" %%b in ("%%~na") do (
        echo ren "%%~a" "%%b_%%c_%%d%%~xa"
    )
)
pause

试试这样能否看到集数?
作者: xinjinjie    时间: 2017-4-19 21:11

回复 13# ShowCode

感谢ShowCode大大指点,刚才测试新代码,集数有了,但是改名结果的文件名不是想要的内容格式。

显示在CMD界面的新文件名是“FLsnow&SumiSora_GRANBLUE FANTASY-The Animation_01.mkv”,想要的新文件名是“GRANBLUE FANTASY_01.mkv”这种。
作者: ShowCode    时间: 2017-4-19 22:00

回复 14# xinjinjie


@echo off
for %%a in ("*GRANBLUE FANTASY*.mkv" "*GRANBLUE FANTASY*.ass") do (
    for /f "tokens=2,4 delims=[]-" %%b in ("%%~na") do (
        echo ren "%%~a" "%%b_%%c%%~xa"
    )
)
pause
作者: xinjinjie    时间: 2017-4-20 21:20

本帖最后由 xinjinjie 于 2017-4-20 21:22 编辑

回复 15# ShowCode


    感谢ShowCode大大指点,刚才测试新代码,能达到改名效果了,不过看代码的红色部分再结合自己在顶楼描述的需求情况后,感觉这个代码似乎不是很符合1L的需求描述,所以自己在这个代码上稍微修改了一下改名的文件名指定
  1. @echo off
  2. for %%a in ("*GRANBLUE FANTASY*.mkv" "*GRANBLUE FANTASY*.ass") do (
  3.     for /f "tokens=2,4 delims=[]-" %%b in ("%%~na") do (
  4.          ren "%%~a" "GRANBLUE_FANTASY_%%c%%~xa"
  5.     )
  6. )
  7. pause
复制代码
自己测试效果,能达到自己想要的指定一个文件名、获取原文件名中的集数组合到指定的文件名里改成新的文件名的效果,不过好像只能针对“[FLsnow&SumiSora][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv”这个格式内容的原文件名才有效?
在1L提到过的,Arrow.S05E18.1080p.WEB-DL.DD5.1.H264-RARBG.mkv 用这个代码似乎就不行了,推测为集数部分的格式不同,还请ShowCode大大指点该如何修改代码来对应这种格式的呢?
作者: xinjinjie    时间: 2017-4-23 16:04

回复 15# ShowCode

已测试用这个代码修改文件名关键字来给其他名字内容的视频和字幕改名,发现有小问题。

比如:[Suzu-Kaze&LoliHouse] Sword Oratoria - 01 [WebRip 1920x1080 HEVC-yuv420p10 AAC]/[Suzu-Kaze&LoliHouse] Sword Oratoria - 01 [WebRip 1920x1080 HEVC-yuv420p10 AAC].mkv,用
  1. @echo off
  2. for %%a in ("*Sword Oratoria*.mkv" "*Sword Oratoria*.ass") do (
  3.     for /f "tokens=2,4 delims=[]-" %%b in ("%%~na") do (
  4.          ren "%%~a" "Sword_Oratoria_%%c%%~xa"
  5.     )
  6. )
  7. pause
复制代码
结果会比较奇怪的在下划线和集数之间、集数和“.”之间都多出一个空格:Sword_Oratoria_ 01 .mkv。

如果是:Arrow.S05E18.1080p.WEB-DL.DD5.1.H264-RARBG.mkv,用
  1. @echo off
  2. for %%a in ("*Arrow.S05*.mkv" "*Arrow.S05*.ass") do (
  3.     for /f "tokens=2,4 delims=[]-" %%b in ("%%~na") do (
  4.          ren "%%~a" "Arrow.S05_%%c%%~xa"
  5.     )
  6. )
  7. pause
复制代码
来改名的话,改完后集数不见了……“Arrow.S05_.mkv”。有没有办法调整这个代码后,只需要调整文件名的关键字和集数的关键字,就可以通用的办法呢?
作者: ShowCode    时间: 2017-4-24 21:01

能否写出通用的代码,取决于是否能够总结出通用的规律。
以15楼代码为例:
tokens=2,4 delims=[]- 表示以左括号或右括号或减号为列分隔符,取第二列和第四列

[FLsnow&SumiSora][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv
第1列是红色
第2列是黄色
第3列是绿色
第4列是蓝色

请告诉我 Arrow.S05E18.1080p.WEB-DL.DD5.1.H264-RARBG.mkv 的规律是什么?
它的规律跟 [FLsnow&SumiSora][GRANBLUE FANTASY-The Animation][01][TVRIP][1080p][HEVC_AAC].mkv 的规律一样吗?
作者: xinjinjie    时间: 2017-4-24 22:28

回复 18# ShowCode


    感谢ShowCode大大指点,这才明白,识别了关键字后,原来做的是以左括号或右括号或减号为列分隔符,取第二列和第四列,这样来达到的获取文件名和集数的效果的。
tokens=2,4 delims=[]-,这里能不能写成类似判断关键字的这种“in ("*Sword Oratoria*.mkv" "*Sword Oratoria*.ass") ”,用来判断文件名中是否含有这个有规律的“E”+“数字”组合起来的集数,如果能判断到这种组合的集数,就将E后面的数值取出来做新文件名的集数,这应该是一个规律,只要能按照这个规律取到集数,可以像L16我改的改名部分那样,在代码里直接指定新的文件名,组合上取到的集数后,就达到预期效果了,只是不知道该怎么写。
作者: ShowCode    时间: 2017-4-25 09:40

回复 19# xinjinjie


delims只能以指定的字符做分隔符,它本身不具备判断功能。
如果所有文件名里面都包含 S数字数字E数字数字 这种格式,那么可以想别的办法来实现。
作者: pcl_test    时间: 2017-4-25 17:41

本帖最后由 pcl_test 于 2017-4-25 17:43 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str1=GRANBLUE FANTASY"
  3. set "str2=[??]"
  4. set "str1_1=%str1%"
  5. set "str2_1=%str2%"
  6. for %%a in (.,$,^^^^,[,]) do (
  7.     set "str1_1=!str1_1:%%a=\%%a!"
  8.     set "str2_1=!str2_1:%%a=\%%a!"
  9. )
  10. set "str2_1=%str2_1:?=[0-9]%"
  11. set "t=%str2%fedcba987654321"&set /a n=0x!t:~15,1!
  12. for /l %%a in (0 1 %n%) do (
  13.     if "!str2:~%%a,1!" equ "?" set _#%%a=%%a
  14. )
  15. for /f "delims=" %%a in ('dir /a-d/b *.mkv *.ass^|findstr /irc:".*%str1_1%.*%str2_1%"') do (
  16.     call :rn "%%a"
  17. )
  18. pause&exit
  19. :rn
  20. set "fn=%~n1"
  21. set "fn=!fn:%str1%=!"
  22. set m=0
  23. :loop
  24. set "s="
  25. set "tmp=!fn:~%m%,%n%!"
  26. for /f "tokens=2 delims==" %%b in ('set _#') do set "s=!s!!tmp:~%%b,1!"
  27. for /f "tokens=1* delims=9876543210" %%c in ("#!s!") do (
  28.     if "%%c%%d" equ "#" (
  29.         for /l %%e in (0 1 9) do set "tmp=!tmp:%%e=!"
  30.         if "!tmp!" equ "%str2:?=%" (
  31.             echo;ren "%~1" "%str1%_!s!%~x1"
  32.             goto :eof
  33.         )
  34.     )
  35. )
  36. set /a m+=1
  37. if "!tmp!" neq "" goto loop
复制代码

作者: xinjinjie    时间: 2017-4-25 21:59

回复 21# pcl_test


    感谢版主的代码指点,已测试目前遇到的几种文件名,通过修改str1、str2的关键字内容可以正确的判断到文件名和集数,通过调整ren语句中的新文件名部分代码,可以用关键字来改名,也可以在这里强行指定一个新文件名,最后可以和获取到的集数组合成新的文件名,完全符合设想的功能和效果。再次感谢版主大大的分享和指点,谢谢。




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2