Board logo

标题: [文本处理] [已解决]如何提取原文件名中连续的字母数字来重命名文件 [打印本页]

作者: 34205    时间: 2015-9-26 23:44     标题: [已解决]如何提取原文件名中连续的字母数字来重命名文件

本帖最后由 pcl_test 于 2017-4-13 10:09 编辑

如题:
1、项目有很多带有编号的文件,需要Bat对每个文件按一定规则重命名
2、原始格式如:
(格式包含:字母、数字、符号、中文,除了所说的编号(蓝色)是固定之外,其他很随机)
(符号只有三个 -_ (即常用命名符号:减号、下划线、空格))

Mark31_DMK-007-开发文档.doc
Install_ISKA396-安装补丁.Temp
Odfm09632M芯片.Doc
方案Sk5_ISKA9531.Js
统计表20140312KSIM325FromLiHua月报.xls


4、处理规则:
按 【连续三个以上字母+零或一个符号+连续三个以上数字】(难点在于连续),作为识别【编号】,存储编号到编号记录的.txt,再以 【编号+中文】为新文件名命名文件

5、个人想法:我也是新手,单单不考虑动手一番就伸手,可能会耽误热心的前辈的时间,所以把我的想法和困难写出来(以下版主的做法远远超过了我的思路,So以下个人理解请忽略):
1)取出一个文件名,先逐字分割,For命令可以
2)判断连续三个以上数字(因为英文很多,数字则较容易判断三个连续),判断方法是:遇到第一个数字则开始计数,存到变量A,第二个还是数字则计数加一,更新变量A,如此类推。直到下一个不是数字则计数清零,即不满足数字。通过判断计数大于等于3则变量满足规则,但程序还要继续判断数字要满足到最长的连续数字)      :这里面的难点在于如何判断同时又存储直到不是数字为止
3)数字前面一定是一个或零个符号,所以把变量A前一位找出来,其一定满足是符号或字母(如果不是符号字母则前面的单单三个数字就不满足规则了),满足则更新A    :难点在于怎么提取前一位
4)再对前一位再读取,其一定满足是字母(如果不是字母则又不满足了),再对前前一位读取判断是否是字母,如此知道不是字母为止,不断更新变量A (向前取是因为保证一样统计大于3个字母)     :难点在于 如何向前取字符,这个论坛里面可没有发现向前取字符的
5)获得变量A判断A的前面字母大于三个,则变量A即是编号,再提取文件名中的中文,就可以按 编号+中文 为新文件名命名文件


6、本批处理的处理规则适合于:存档管理里面的【产品编号】自动识别,有些复杂的判断规则。所以我想可能要花费前辈的一些时间,不过做出来了实用性还是很大的。

7、挂出来大家练练手,谢谢了,最好纯Bat码哈,嘿嘿。

节省大家时间就这么创建测试吧:
  1. @echo off
  2. Echo "" >%CD%\Temp_Mark31_DMK-007-开发文档.doc
  3. Echo "" >%CD%\Temp_Install_ISKA396-安装补丁.Temp
  4. Echo "" >%CD%\Temp_Odfm09632M芯片.Doc
  5. Echo "" >%CD%\Temp_方案Sk5_ISKA9531.Js
  6. Echo "" >%CD%\Temp_统计表20140312KSIM325FromLiHua月报.xls
复制代码

作者: pcl_test    时间: 2015-9-27 00:51

本帖最后由 pcl_test 于 2015-9-27 10:01 编辑
  1. //&cls&dir/a-d/b|findstr /vc:"%~nx0"|cscript -nologo -e:jscript "%~f0"&pause&exit/b
  2. var fso = new ActiveXObject('Scripting.FileSystemObject');
  3. var files = WScript.StdIn.ReadAll().split(/\r?\n/);
  4. for (var i=0;i<files.length;i++){
  5.     var ext = files[i].replace(/.+?(\.[^.]+)$/,'$1');
  6.     var m = files[i].match(/[a-z]{3,}[\s\-_]?\d{3,}/i);
  7.     if(m){
  8.         var newname = m+files[i].replace(/[^\u4e00-\u9fa5]/g,'')+ext;
  9.         WSH.echo(files[i]+' --> '+newname);
  10.         //fso.MoveFile(files[i],newname);
  11.     }
  12. }
复制代码

作者: 34205    时间: 2015-9-27 09:11

@pcl_test,哈哈,中秋佳节节日快乐!这么早就有答案了,以上Bat测试完美,直接正则简单粗暴效率也高,值得学习
作者: 34205    时间: 2015-9-27 09:22

答案有了,值得像我这种水平学习的地方:
1、 match(/[a-z]{3,}[\s\-_]?[0-9]{3,}/i) ,正则用法:直接以3位以上英文加符号加三位以上数字,这个直截了当
2、 按照Bat的思路,我还想着中文是不是要搞个中文字库呢,/[^\u4e00-\u9fa5]/g ,直接从编码下手,哈哈
3、Bat里套用VBS,答案直接一个Bat文件可搞定,无缝融合啊,Good

中秋佳节,谢谢大家...
作者: 回家路上    时间: 2015-9-27 09:30

本帖最后由 回家路上 于 2015-9-27 09:48 编辑

pcl已经用了JScript了,我就用批处理试了试O(∩_∩)O!
  1. @echo off & setlocal enabledelayedexpansion
  2. ::文件所放文件夹,测试是当前路径的tmp文件夹自行修改
  3. for /f "delims=" %%i in ('dir /b /a-d^|findstr /v "%~nx0"') do (
  4. set file=%%i& set identify=
  5. set filename=%%~ni
  6. call :parse !filename! identify chinese
  7. echo;%%i --》 !identify!!chinese!%%~xi
  8. )
  9. pause & exit /b
  10. :parse [string] [identify] [chinese]
  11. set str=%~1& set ch=& set num=& set sy=& set result=& set c=& set end=
  12. :lp
  13. set isC=& set isN=& set isS=
  14. if "%str:~,1%" geq "a" set /a isC+=1
  15. if "%str:~,1%" leq "Z" set /a isC+=1
  16. if "%isC%"=="2" (
  17. if not defined end (
  18. if not defined sy (
  19. if defined num (
  20. if !num! geq 3 (
  21. set end=1
  22. ) else set ch=& set num=& set sy=& set result=
  23. ) else (
  24. set result=!result!%str:~,1%
  25. set /a ch+=1
  26. )
  27. ) else set num=& set sy=& set ch=1& set result=%str:~,1%
  28. )
  29. ) else (
  30. if %str:~,1% geq 0 set /a isN+=1
  31. if %str:~,1% leq 9 set /a isN+=1
  32. if "!isN!"=="2" (
  33. if not defined end if defined ch (
  34. if !ch! geq 3 (
  35. set result=!result!%str:~,1%
  36. set /a num+=1
  37. ) else set ch=& set num=& set sy=& set result=
  38. )
  39. ) else (
  40. if defined num if !num! geq 3 set end=1
  41. if "%str:~,1%"=="-" set isS=1
  42. if "%str:~,1%"=="_" set isS=1
  43. if "%str:~,1%"==" " set isS=1
  44. if defined isS (
  45. if not defined end if not defined sy (
  46. if defined ch (
  47. set result=!result!%str:~,1%
  48. set sy=1
  49. )
  50. )
  51. ) else set c=!c!%str:~,1%
  52. )
  53. )
  54. if "%str:~1,1%" neq "" (set str=%str:~1%& goto :lp)
  55. if !num! geq 3 set %~2=!result!& set %~3=!c!
  56. goto :eof
复制代码

作者: 34205    时间: 2015-9-27 09:44

本帖最后由 34205 于 2015-9-27 09:57 编辑

回复 5# 回家路上

节日快乐 ,纯Bat编写确实不容易,比较复杂,很多疑问被解决了。
测试还有些错误哈,运行结果:
==========================
系统找不到指定的路径
ISKA396安装补丁
DMK-007开发文档
Odfm09632芯片
芯片
芯片
ISKA9531方案
KSIM325统计表月报
请按任意键继续. . .
==========================
1、 M芯片 部分那里可能处理上还不太准确造成重复计数了,所以重命名可能会错误了
作者: 回家路上    时间: 2015-9-27 09:51

回复 6# 34205


我这边是测试了才放上去的,可能是环境不同吧不知道。
中秋快乐,玩去了。
作者: 34205    时间: 2015-9-27 09:58

回复 7# 回家路上

再次测试完美了,Good,好好消化先,哈哈
=============================
Install_ISKA396-安装补丁.Temp --》 ISKA396安装补丁.Temp
Mark31_DMK-007-开发文档.doc --》 DMK-007开发文档.doc
Odfm09632M芯片.Doc --》 Odfm09632芯片.Doc
方案Sk5_ISKA9531.Js --》 ISKA9531方案.Js
统计表20140312KSIM325FromLiHua月报.xls --》 KSIM325统计表月报.xls
请按任意键继续. . .
=============================

玩得尽兴,放心去玩吧..........
作者: CrLf    时间: 2015-9-27 15:19

来一枚 powershell:
  1. $pattern = '[a-z]{3,}[\s\-_]?\d{3,}'
  2. dir | ? { $_.name -match $pattern } | % {
  3. $_.name + ' --> ' + ($_.basename -replace $pattern,'.log') + $_.extension
  4. }
复制代码





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