找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
楼主: rdingding1

[文件操作] [已解决]批量文件断点续处理,关于findstr在处理记录文件中查找无效的问题

[复制链接]
 楼主| 发表于 2025-6-22 16:01:42 | 显示全部楼层
回复 14# aloha20200628

没什么特别的规律,不是变量延迟的原因,按你处指点试验如下:
1)工作目录C:
2)dir /b/s/a-d  *.txt>d:\filesrecord1.txt
3)\ 作 \\ 全局替换
4)dir /b/s/a-d *.txt|findstr /vxlig:"d:\filesrecord.txt">d:\filesrecord2.txt
     d:\filesrecord2.txt有结果(按预计,应该为空)
     说明:/vlig: 也试验了也有结果,结果数量与总数量有关,总数量越大,结果越多
5)将d:\filesrecord2.txt的结果\ 作 \\ 全局替换,逐条在filesrecord1.txt查找,均能找到
6)查看filesrecord2.txt,没有发现什么特殊符号,范例如“C:\Users\rding\Downloads\EasyFileCount\注意事项.txt”

感觉还是findstr /vlig 本身的原因吧,不太清楚它的原理。
 楼主| 发表于 2025-6-22 16:24:15 | 显示全部楼层
回复 15# 77七

我试了一下,的确会漏掉一些,但是将漏掉的这些追加到排除文件,就成功排除了,一个不漏。

文件多时,要多次追加,而且有时剩下几个就是不能再次排除。其实我知道都运行完了,也不影响结果,只是想看下能否找到是什么原因。

建议楼主可以试试8楼文件属性的方法,我觉得这个方法挺好的,相当于给文件做了一个标记,包括dir del robocopy等等都能按属性操作配合,我觉得大多数情况可以用,而且很好用。

这个方法确实很好,就是不知道文档的存档属性不修改回会有什么影响?

另外建议,不要随意修改1楼,影响阅读,有关键的可以补充,其它直接回帖就行。

确实感觉老是修改1楼,有点怪,感觉不太好。嗯,后面还是按回帖来补充。
不知道论坛能否在当楼层中回复?
年纪大了,思路有点乱,基础较差,时间也比较碎片,所以感觉表达老是想改,改来改去就有点乱了,汗!
 楼主| 发表于 2025-6-22 17:22:51 | 显示全部楼层
本帖最后由 rdingding1 于 2025-6-22 17:24 编辑

目前待改进的点:
1)findstr无法彻底筛查
    更改思路,不使用findstr,该条实现的目的是“两个文本集求差集”
    目前可以用grep或awk(本站第三方工具下载中的最新64位版本,和脚本放置到一起)替换原方法二的第23行或方法三的第27行
     grep方案:不会出现筛查重复,文件多时效率比findstr略低
  1. dir /b /s /a-d "%input_dir%\*.txt" | grep64 -F -v -f "%processed_list%">$.#
复制代码
awk方案:不会出现筛查重复,文件多时效率极高(awk的数组类似内存hash对应,18K个文件,记录文件空/满/一半时间分别为26s/1s/12s)
  1. dir /b /s /a-d "%input_dir%\*.txt">@.@
  2. gawk64 "NR==FNR{ a[$0]=$0 } NR>FNR{ if(a[$0] == """"""){ print $0}}" "%processed_list%" @.@>$.#
复制代码
2)使用 延迟变量 导致的特殊字符! 丢失
     在用18K个样品文件测试时发现有10个文件名的 ! 丢失了,查询发现使用延迟变量造成,目前的解决方案是采用临时文件做替换中转,这样又会造成IO读写增加,所以去除变量追加,缩小延迟变量范围,改回单次直接>> 日志文件和记录文件

3)关于“在主循环内反复追写 >> 日志文件和记录文件,此条效率及IO读写问题”,原采用变量缓存一段再批量写入方式,因为批处理变量小于8190 以及 延迟变量 导致的特殊字符!引发的问题,暂时不优化。
实际18K个文件路径的文本也不大,后面用python重写时,可以1K或0.5K个文件记录一次。

最后,目前的脚本(方法四,采用awk)如下
  1. @echo off
  2. rem 使用说明:断点续处理.cmd 待处理路径
  3. rem 使用说明:处理txt文档
  4. rem ========== 配置区域 ==========
  5. set "input_dir=%~1"
  6. set "log_file=operation.log"
  7. set "processed_list=processed_files.txt"
  8. rem ========== 初始化 ==========
  9. if not exist "%input_dir%" (
  10.     echo 错误:目录不存在
  11.     echo 错误:目录不存在 >> "%log_file%"
  12.     exit /b 1
  13. )
  14. echo 开始处理: %date% %time%
  15. echo 开始处理: %date% %time% > "%log_file%"
  16. if not exist "%processed_list%" (
  17.     echo 记录开始 > "%processed_list%"
  18. )
  19. set t=%time%
  20. rem ========== 主循环 ==========
  21. set /a count = 1
  22. dir /b /s /a-d "%input_dir%\*.txt">@.@
  23. gawk64 "NR==FNR{ a[$0]=$0 } NR>FNR{ if(a[$0] == """"""){ print $0}}" "%processed_list%" @.@>$.#
  24. for /f "delims=" %%i in ('find /v /c "" $.#') do set totalcount=%%i
  25. set totalcount=%totalcount:*:=%
  26. for /f "delims=" %%a in ($.#) do (
  27.     setlocal enabledelayedexpansion
  28.     set /p =!count! / %totalcount% <nul
  29.     set /p =<nul
  30.     endlocal
  31.     rem  要处理的语句
  32.     echo %%a 已处理 >> "%log_file%"
  33.     echo %%a>>"%processed_list%"
  34.     set /a count += 1
  35. )
  36. del /q $.#
  37. del /q @.@
  38. :: ========== 收尾 ==========
  39. set t1=%time%
  40. if "%t1:~,2%" lss "%t:~,2%" set "add=+24"
  41. set /a "times=(%t1:~,2%-%t:~,2%%add%)*360000+(1%t1:~3,2%%%100-1%t:~3,2%%%100)*6000+(1%t1:~6,2%%%100-1%t:~6,2%%%100)*100+(1%t1:~-2%%%100-1%t:~-2%%%100)" ,"ss=(times/100)%%60","mm=(times/6000)%%60","hh=times/360000","ms=times%%100"
  42. echo 处理完成: %date% %time%
  43. echo 处理完成: %date% %time% >> "%log_file%"
  44. echo 共处理 %totalcount% 个文件,耗时 %hh%:%mm%:%ss%.%ms%  秒
  45. echo 操作日志已保存到: %log_file%
  46. pause
复制代码
发表于 2025-6-22 19:48:34 | 显示全部楼层
本帖最后由 aloha20200628 于 2025-6-22 21:08 编辑

回复 18# rdingding1

如果楼主已有 python 运行环境,亦可用其进一步优化18楼代码,不必下载 awk.exe,不必再全局替换处理记录文件,而且采用 python 的获取 '集合之差' 功能,其效率较高,不妨一试。以下代码可直接替换18楼代码第23行...

  1. python -c "with open('@.@','r',-1) as f1, open('%processed_list%','r',-1) as f2: r=set(f1.read().splitlines()).difference(set(f2.read().splitlines())); print('\r\n'.join(list(r)))">"$.#"
复制代码
再给一个调用 powershell 获取两个文件内容差集的示例代码(用以替换18楼代码第23行)

  1. powershell "Compare-Object (gc '@.@') (gc '%processed_list%') -PassThru">"$.#"
复制代码
当已有 powershell 或者 python 运行环境时,常年未予及时维修的 findstr 即可退场了,尤其是在处理大量包含多字节(如汉字)数据的场合...
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 07:05 , Processed in 0.017831 second(s), 7 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表