Board logo

标题: [文本处理] 【已解决】批处理如何提取两个关键词之间的信息然后以此重命名文件名? [打印本页]

作者: ziranww    时间: 2019-1-29 16:39     标题: 【已解决】批处理如何提取两个关键词之间的信息然后以此重命名文件名?

本帖最后由 ziranww 于 2019-2-11 13:29 编辑

非常感谢论坛里热心的朋友们,特别是@flashercs帮我几次完善了脚本,非常感谢,问题解决了
最终完善版脚本在23楼http://www.bathome.net/redirect. ... 1962&pid=217302
有类似需求的朋友可以参考一下

--------------------------------------
RT,有大量文件需要重命名,改成TXT后发现了一些规律,从其中能提取到有用的信息用于重命名文件。于是在网上查,找到了一款神奇的软件Replace Pioneer,但是研究数个小时后还是没有搞定
看了半天官网上的规则和示例,折腾了几个小时未果。于是在网上查到了论坛,求高手帮忙

需要改名的文件改成TXT打开后是这样的:
  1. 乱码
  2. abcd 乱码 name 乱码 efgh
  3. 乱码
复制代码
说明:
abcd:文件名标记信息开始
efgh:文件名标记信息结束
name:用于提取后重命名到文件名

谢谢了
作者: ziranww    时间: 2019-1-29 16:53

用notepad++打开是这样的,红圈部分是需要提取的文件名
作者: WHY    时间: 2019-1-29 19:07

应该不难。但无真实信息又没有样本,又是挤牙膏的节奏。
作者: ziranww    时间: 2019-1-30 08:52

回复 4# flashercs


    谢谢兄弟,执行后没有成功,关了echo后看到有提示

ECHO 处于打开状态。

E:\test>set "dir=E:\test"

E:\test>powershell.exe -Command "(Select-String -Path 'E:\test\*.*' -Pattern '(?<=model_name\x00)[^\x00]+(?=\x00.*?disp_out1_info)' -Encoding default)|{Rename-Item -LiteralPath $_.Path -NewName $_.Matches[0].Value}"
所在位置 行:1 字符: 119
+ ... ng default)|{Rename-Item -LiteralPath $_.Path -NewName $_.Matches[0]. ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
只允许将表达式作为管道的第一个元素。
    + CategoryInfo          : ParserError: ( [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpressionsMustBeFirstInPipeline
作者: zuodx    时间: 2019-1-30 13:11

perl  python 正则表达式,写个脚本就是了
作者: ziranww    时间: 2019-1-30 14:04

回复 6# zuodx


    这个更不会了
作者: flashercs    时间: 2019-1-30 14:19

回复 6# ziranww

a.bat
  1. @echo off
  2. set "dir=E:\test"
  3. powershell.exe -Command "(Select-String -Path '%dir%\*.*' -Pattern '(?<=model_name\x00)[^\x00]+(?=\x00.*?disp_out1_info)' -Encoding default)|Foreach-object{Rename-Item -LiteralPath $_.Path -NewName $_.Matches[0].Value}"
复制代码

作者: ziranww    时间: 2019-1-30 14:38

回复 7# flashercs


    兄弟,现在没有报错了,但是执行后没有改名
作者: flashercs    时间: 2019-1-30 15:00

好像没有规律可循,不好办;因为乱码部分是随机乱码。
作者: ziranww    时间: 2019-1-30 15:14

回复 9# flashercs


    还是谢谢兄弟了
作者: 523066680    时间: 2019-1-30 16:35

本帖最后由 523066680 于 2019-1-30 16:55 编辑

回复 9# flashercs

    正则应该有一种占位符用来表达常见字符或者明文以外的符号。
在Perl里面是 \p{组合属性},因为Perl基本很多人没装,就不安利楼主了。

丢个砖头
  1. my $s = join('', map { chr } 0..127 );
  2. $s =~s/\p{IsCntrl}//g;
  3. print $s;
复制代码
过滤后的结果
  1. !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
复制代码
建议楼主把eps文件压缩上传到某个网盘让大家下载看看,我用ai和coreldraw导出的eps文件并没有看到类似字段,没法测试。

如果按截图中处理的话大概会这么写
~/model_name\p{IsCntrl}+(.*)\p{IsCntrl}/;
取 $1
作者: lanfogz    时间: 2019-1-30 17:39

本帖最后由 lanfogz 于 2019-1-30 17:51 编辑

我的想法:先过滤乱码,再进行处理。

有个小工具(https://pan.baidu.com/s/1jIrZ5pB9wYyaFhx70GfScw),执行“smooth 文件名”
可以把结果粘贴上来,看看效果


理想的效果是:
  1. @echo off &setlocal enabledelayedexpansion
  2. for /f %%i in ('smooth %1 ^|findstr model_name') do (
  3. set c=%%i
  4. rename %1 !c:10!
  5. goto:break
  6. )
  7. :break
复制代码

作者: WHY    时间: 2019-1-30 19:02

光看图片,猜测所谓的“乱码”指的是 [\x00-\x1F\x7F\x80-\xFF]
也就是 .net 正则中的 [\p{Cc}\p{IsLatin-1Supplement}]
作者: flashercs    时间: 2019-1-31 00:35

本帖最后由 flashercs 于 2019-1-31 09:58 编辑

由NULxE0NUL判断
这是utf8编码打开npp
而utf8编码下,\xE0\x00不存在编码位置,故替换为\xFFFD;
其他乱码同理:
所以文本分隔符应该是控制字符的[\x00-0x1f]和替换符\xFFFD
  1. @echo off
  2. set "dir=E:\test"
  3. powershell.exe -Command "(Select-String -Path "%dir%\*.*" -Pattern '(?<=model_name[\x00-\x1F\uFFFD]+)[^\x00-\x1F\uFFFD]+(?=[\x00-\x1F\uFFFD]*disp_outl_info)' -Encoding utf8)|Foreach-object{Rename-Item -LiteralPath $_.Path -NewName ($_.Matches[0].Value+[System.IO.Path]::GetExtension($_.Path))}"
复制代码

作者: ziranww    时间: 2019-1-31 09:23

非常感谢论坛里热心的网友,已上传样本文件
是creo的prt文件

通过winhex打开看到情况是这样的,我现在通过replace pineer这个软件处理了一下文件,只能通过固定数量字符窜长度实现了一部分文件的提取后重命名,但是还是不完美,发现里面有许多文件命名长度不一样,最完美的是过滤掉乱码,提取两个字符中间的内容
作者: ziranww    时间: 2019-1-31 09:37

回复 11# 523066680


    已上传,感谢版主
作者: flashercs    时间: 2019-1-31 10:00

14楼修改了
作者: ziranww    时间: 2019-1-31 10:05

回复 17# flashercs


    万分感谢兄弟 成功
作者: ziranww    时间: 2019-1-31 10:08

回复 17# flashercs


    再贪婪的问一下,因为有些文件是不同版本,文件名是一样的,能不能实现同样文件名文件,后面加上txt.1,txt.2这样的,谢谢了
作者: flashercs    时间: 2019-1-31 10:45

回复 19# ziranww
  1. @echo off
  2. set "dir=E:\test"
  3. powershell -Command "(Select-String -Path '%dir%\*.*' -Pattern '(?<=model_name[\x00-\x1F\uFFFD]+)[^\x00-\x1F\uFFFD]+(?=[\x00-\x1F\uFFFD]*disp_outl_info)' -Encoding utf8)|ForEach-Object {$baseName = $_.Matches[0].Value + [System.IO.Path]::GetExtension($_.Path); $i = 0; $newName = $baseName; while ($true) {try {Rename-Item -LiteralPath $_.Path -NewName $newName -ErrorAction Stop; break; }catch {$newName = $baseName + '.' + (++$i); }}}"
复制代码

作者: ziranww    时间: 2019-1-31 10:49

回复 20# flashercs


    谢谢大神,完美
作者: ziranww    时间: 2019-1-31 16:24

回复 20# flashercs


    大神再问一下,我11点多执行的脚本,到现在还没有结束,大概1W多个文件,11G多点。看任务管理器,CPU还有占用的,30%不到点,硬盘读写基本上没有了,之前看是有一点的
是不是文件太多了?
作者: flashercs    时间: 2019-1-31 18:01

本帖最后由 flashercs 于 2019-1-31 19:42 编辑

加个进度看看吧,不知处理到哪里了。
  1. @echo off
  2. REM UTF8编码,过滤控制字符和UTF8不能识别的字符后,选择字符串作为文件名并重命名文件。
  3. set "dir=%~dp0."
  4. powershell -Command "foreach ($item in (Get-ChildItem -LiteralPath \"%dir%\" -Filter *.* -File)) { if ([System.IO.File]::ReadAllText($item.FullName, [System.Text.Encoding]::UTF8) -match '(?<=model_name[\x00-\x1F\uFFFD]+)[^\x00-\x1F\uFFFD]+(?=[\x00-\x1F\uFFFD]*disp_outl_info)') { $baseName = $Matches[0] + $item.Extension; $i = 0; $newName = $baseName; while (Test-Path -LiteralPath (Join-Path -Path $item.DirectoryName -ChildPath $newName)) { $newName = $baseName + '.' + (++$i);} Write-Host 'Renaming file ' -NoNewline; Write-Host $item.FullName -NoNewline -ForegroundColor Green; Write-Host ' to ' -NoNewline; Write-Host $newName -ForegroundColor Green; Rename-Item -LiteralPath $item.FullName -NewName $newName; }}"
  5. pause
  6. exit /b
复制代码

作者: ziranww    时间: 2019-1-31 19:25

回复 23# flashercs


    好像提示有点问题
Renaming file E:\test\1246.prt to ZKQ3003003.prt
Rename-Item : 无法重命名,因为“1246.prt”处不存在项。
所在位置 行:1 字符: 637
+ ... oundColor Green; Rename-Item -LiteralPath $item -NewName $newName; }}
+                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: ( [Rename-Item],PSInvalidOperationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand
作者: flashercs    时间: 2019-1-31 19:43

回复 24# ziranww

                                      
已修改
作者: ziranww    时间: 2019-1-31 19:55

回复 25# flashercs


    好的,不把文件后缀改成txt直接处理会不会有问题?
作者: flashercs    时间: 2019-1-31 19:59

回复 26# ziranww


    测试目录测试一下!
默认筛选的是 *.*
作者: lanfogz    时间: 2019-2-1 09:51

  1. @echo off &setlocal enabledelayedexpansion
  2. for /r %%a in (*.txt) do (
  3.   call:r %%a
  4. )
  5. goto:eof
  6. :r
  7.   for /f %%i in ('smooth %1 ^|findstr model_name') do (
  8.     set c=%%i
  9.     set k=!c:~0,10!
  10.     set v=!c:~10!
  11.     if "!k!" equ "model_name" (
  12.       if "!v!" neq "" (
  13.         rename %1 !v!
  14. if errorlevel 0 (echo %1 to !v!) else (echo %1 to !v! ---- fail)
  15. goto:eof
  16.       )
  17.     )
  18.   echo %1 ---- not found
  19.   )
复制代码
https://pan.baidu.com/s/1o23mHiKZBrfNq_P73SVG9A
重在参与!
作者: ziranww    时间: 2019-2-13 11:06

回复 27# flashercs


    你好,兄弟,用你的脚本把所有文件处理好了,现在又发现一个问题,重命名后的文件名比如是这样的:
a.prt
a.prt.1
a.prt.2
a.prt.3
.....
a.prt.250
我看了一下最大的文件到250,之前没注意,文件名应该是第一个开始就加.1,应该是这样的
a.prt.1
a.prt.2
a.prt.3
a.prt.4
.....
a.prt.251

我用原来找的几个批量命名的软件都无法实现扩展名,再求一个批量的脚本,谢谢了
作者: flashercs    时间: 2019-2-13 15:41

回复 29# ziranww

RenameFiles.bat
  1. @echo off
  2. REM 重命名文件为其扩展名序号+1
  3. set "dir=E:\Dest\dest3"
  4. Powershell -Command "(Get-ChildItem -LiteralPath \"%dir%\" -Filter '*.*' -File|ForEach-Object {$ext = $_.Extension.Substring(1); if ($ext -match '^\d+$') {$id = [int]$ext}else {$id = 0}[PSCustomObject]@{'id' = $id; 'fileInfo' = $_}})|Sort-Object -Descending -Property 'id'|ForEach-Object {if ($_.id -ne 0) {$newName = $_.fileInfo.BaseName}else {$newName = $_.fileInfo.Name}$newName = $newName + '.' + ($_.id + 1); Write-Host ('Rename File \"' + $_.fileInfo.FullName + '\" to \"' + $newName + '\"'); Rename-Item -LiteralPath $_.fileInfo.FullName -NewName $newName}"
  5. pause
  6. exit /b
复制代码

作者: ziranww    时间: 2019-2-13 15:47

回复 30# flashercs


    谢谢兄弟,分分种搞定了




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