Board logo

标题: [文件操作] 【已解决】统计每个TXT文件中【<img】出现的次数,将其加入到每个文件名中。 [打印本页]

作者: chable    时间: 2020-10-30 14:21     标题: 【已解决】统计每个TXT文件中【<img】出现的次数,将其加入到每个文件名中。

统计每个TXT文件中【<img】出现的次数,将其加入到每个文件名中。


同一文件夹下有X个子文件夹,每个子文件夹里都有一些TXT文件,都是UTF-8编码。

需求总述:
批量统计文件夹及子文件夹里的每个TXT文件中【<img】出现的次数,将这个数量加入到每个文件名中。

比如:
【郑板桥草书字帖一幅.TXT】 这个文件中 【<img】这串代码出现了19次,则将文件名改为【郑板桥草书字帖一幅(共19张图片).TXT】

测试文件见附件

报酬:5元(以最早实现为准)

目前状态:已经解决
作者: zaqmlp    时间: 2020-10-30 14:37

5元???这就很尴尬了
作者: qixiaobin0715    时间: 2020-10-30 15:17

本帖最后由 qixiaobin0715 于 2020-10-30 15:36 编辑

好像不行,统计的只是img出现的行数,不是img的数量
  1. @echo off
  2. for /r %%i in ("*.txt") do (
  3.     for /f %%a in ('type "%%i"^|find /c "<img"') do (
  4.         ren "%%i" "%%~ni(共%%a张图片).txt"
  5.     )
  6. )
  7. pause&exit
复制代码

作者: chable    时间: 2020-10-30 16:50

回复 3# qixiaobin0715


   统计出来的数目不对。测试了一下,正确应该是4、45.您的代码结果是3、23
作者: WHY    时间: 2020-10-30 19:05

本帖最后由 WHY 于 2020-10-31 00:06 编辑
  1. @echo off
  2. PowerShell "dir . -Filter *.txt -Recurse | forEach{$str=[IO.File]::ReadAllText($_.FullName); $n=($str -split '<img').Count-1; ren $_.FullName -NewName($_.BaseName + '(' + $n + ')' + $_.Extension) -WhatIf}"
  3. pause
复制代码

作者: Batcher    时间: 2020-10-31 12:49

回复 1# chable


BAT调用grep.exe命令行工具
http://bcn.bathome.net/s/tool/index.html?key=grep
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "SrcFolder=D:\Test\测试文件\"
  4. if not exist "%SrcFolder%" (
  5.     goto :eof
  6. ) else (
  7.     cd /d "%SrcFolder%"
  8. )
  9. for /f "delims=" %%a in ('dir /b /a-d *.txt') do (
  10.     for /f "delims=" %%b in ('grep -o "<img" "%%a" ^| find /c /v ""') do (
  11.         ren "%%a" "%%~na(共%%b张图片)%%~xa"
  12.     )
  13. )
复制代码

作者: 小渣飞    时间: 2020-11-1 00:26

本帖最后由 小渣飞 于 2020-11-1 00:31 编辑

大佬这里的goto :eof是去哪,没看到 call 呀
作者: chable    时间: 2020-11-1 09:45

回复 5# WHY


    好像统计到了数目了,但是没有最后执行重命名的动作。
作者: chable    时间: 2020-11-1 09:50

回复 6# Batcher


    下载了GREP.EXE后,要放到哪个文件里?
作者: chable    时间: 2020-11-1 09:52

回复 6# Batcher

我下载了2.21 grep.exe 。放到C:\WINDOWS下,运行完后,都只能统计到1张图片。功有已经用其他的代码实现了,感谢您!
作者: Batcher    时间: 2020-11-1 21:29

回复 10# chable


    我这边测试 grep 3.0 没有问题
作者: WHY    时间: 2020-11-2 00:01

  1. @if (0)==(0) echo off
  2. for /f "tokens=1*" %%i in ('dir /b /a-d /s *.txt ^| cscript //nologo //e:jscript "%~f0"') do (
  3.     echo ren "%%j" "%%~nj(%%i)%%~xj"
  4. )
  5. pause & exit
  6. @end
  7. function getStrNumber(file){
  8.     var ado = new ActiveXObject('ADODB.Stream');
  9.     ado.Type = 2;
  10.     ado.Mode = 3;
  11.     ado.Charset = 'utf-8';
  12.     ado.Open();
  13.     ado.LoadFromFile(file);
  14.     return ado.ReadText(-1).split('<img').length - 1;
  15. }
  16. while(!WSH.StdIn.AtEndOfStream){
  17.     var f = WSH.StdIn.ReadLine();
  18.     WSH.Echo('' + getStrNumber(f) + ' ' + f);
  19. }
复制代码

作者: WHY    时间: 2020-11-2 00:04

本帖最后由 WHY 于 2020-11-2 00:18 编辑

GNU sed 4.3
  1. @echo off
  2. for /f "delims=" %%i in ('dir /b /a-d /s *.txt') do (
  3.     for /f %%j in ('sed "s/<img/\n&/g" "%%i" ^| find /c "<img"') do (
  4.         echo ren "%%i" "%%~ni(%%j)%%~xi"
  5.     )
  6. )
  7. pause
复制代码

作者: 三十年前    时间: 2020-11-3 11:06

回复 13# WHY


    哥,你这代码有问题,第三段中间的 sed 应该是 set 吧?
我改过来后发现运行还是有问题。
作者: qixiaobin0715    时间: 2020-11-3 15:31

纯批好像也能解决:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /r %%i in ("*.txt") do (
  4.     set n=0
  5.     for /f "delims=" %%a in ('type "%%i"') do (
  6.         set str=%%a
  7.         set "str=!str:img alt= <img alt!"
  8.         for %%k in (!str!) do (
  9.             set var=%%k
  10.             if not "!var!"=="!var:<img=!" set /a n+=1
  11.         )
  12.     )
  13.     ren "%%i" "%%~ni(共!n!张图片)%%~xi"
  14. )
  15. pause&exit
复制代码

作者: qixiaobin0715    时间: 2020-11-4 13:57

本帖最后由 qixiaobin0715 于 2020-11-4 14:00 编辑

由于UTF-8编码的影响,部分双引号也会出现乱码,为保险起见,在15楼代码7、8行之间插入一行   set "str=!str:"=!"    最好。
作者: qixiaobin0715    时间: 2020-11-4 15:18

修改和简化后的完整代码:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /r %%i in ("*.txt") do (
  4.     set n=0
  5.     for /f "delims=" %%a in ('type "%%i"') do (
  6.         set "str=%%a"
  7.         set "str=!str:img alt= <img alt!"
  8.         set "str=!str:"=!"
  9.         for %%k in (!str!) do (
  10.             if "%%k"=="<img" set /a n+=1
  11.         )
  12.     )
  13.     ren "%%i" "%%~ni(共!n!张图片)%%~xi"
  14. )
  15. pause&exit
复制代码

作者: WHY    时间: 2020-11-4 19:29

回复 14# 三十年前


    是 sed.exe 不是 set,脚本上面一行有下载链接。
作者: WHY    时间: 2020-11-4 19:35

纯批的话,改一下代码页可以避免乱码问题。
  1. @echo off & setlocal enabledelayedexpansion
  2. chcp 65001
  3. for /f "delims=" %%i in ('dir /b /a-d /s *.txt') do (
  4.     set n=0
  5.     for /f "delims=" %%j in ('type "%%i"') do (
  6.         set "s=%%j"
  7.         set "s=!s:"=!"
  8.         for %%k in ("!s:<img=" "!") do set /a n+=1
  9.         set /a n-=1
  10.     )
  11.     echo ren "%%i" "%%~ni(!n!)%%~xi"
  12. )
  13. pause
复制代码
保存为 test.bat,编码格式选 utf-8 without BOM。
Active code page: 65001
ren "E:\Test\需求.txt" "需求(2).txt"
ren "E:\Test\测试文件\怀素《自叙帖》草书书法图片.txt" "怀素《自叙帖》草书书法图片(45).txt"
ren "E:\Test\测试文件\蔡京《大观御笔记》行书欣赏.txt" "蔡京《大观御笔记》行书欣赏(4).txt"
Press any key to continue . . .

作者: qixiaobin0715    时间: 2020-11-4 19:43

回复 19# WHY

乱码问题原来可以这样解决,以前不知道,学到了。谢谢!!!
作者: qixiaobin0715    时间: 2020-11-7 09:50

第5行加上findstr过滤一下效率应当能够得到提升:
'type "%%i"^|findstr /c:"img alt"'
作者: qixiaobin0715    时间: 2020-11-10 10:02

本帖最后由 qixiaobin0715 于 2020-11-12 13:17 编辑

练练手,去掉一层for循环,复习一下call的用法,效率差点。
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /r %%i in ("*.txt") do (
  4.     set n=0
  5.     for /f "delims=" %%a in ('type "%%i"^|findstr /c:"img alt"') do (
  6.         set "str=%%a"
  7. :a
  8.         echo "!str!"|findstr /c:"img alt">nul&&set str=!str:*img alt=!&&set /a n+=1&&call :a
  9.     )
  10.     ren "%%i" "%%~ni(共!n!张图片)%%~xi" 2>nul
  11. )
  12. goto :eof
复制代码

作者: WHY    时间: 2020-11-11 22:46

本帖最后由 WHY 于 2020-11-11 22:48 编辑

回复 22# qixiaobin0715


    for 循环内部(语句块内部)应该不能放置标签的吧?可以把 :a 标签放到 for 循环体外面。
作者: qixiaobin0715    时间: 2020-11-11 22:56

本帖最后由 qixiaobin0715 于 2020-11-12 06:50 编辑

回复 23# WHY

通常是不行。这里是特例,call循环完成后会继续完成它下面的代码,中间ren会报错,增加 2>nul消除。内层for循环结束一次(每个文件读取完成)后,会正常执行一次ren。这里是非常规的用法。只是博得一笑而已。
报错原因是无法识别%%i。




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