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

[文本处理] 批处理怎样按条件插入行填补行?

本帖最后由 娜美 于 2023-8-20 14:04 编辑

补充一些a文本
  1. a.txt  ANSI编码
  2. 19:37:30 August 16 2023>   企业 名称:优 美 利 A
  3. 19:37:31 August 16 2023>   ++++
  4. 19:37:32 August 16 2023>   企业 名称:利海 B
  5. 19:37:33 August 16 2023>    +
  6. 19:37:34 August 16 2023>   企业 名称:利海 01:C (A)
  7. 19:37:35 August 16 2023>   +
  8. 19:37:36 August 16 2023>   企业 名称:海
  9. 19:37:39 August 16 2023>   退出
  10. 20:37:30 August 16 2023>   企业 名称:利海 B
  11. 20:39:30 August 16 2023>   企业 名称:利海 B
  12. 20:38:31 August 16 2023>   退出
  13. 20:37:30 August 16 2023>   企业 名称:利
  14. 20:39:30 August 16 2023>   +
  15. 20:39:30 August 16 2023>   +
  16. 20:39:30 August 16 2023>   +
  17. 20:39:30 August 16 2023>   退出
  18. 20:39:30 August 16 2023>   企业 名称:利海 B
  19. 20:38:31 August 16 2023>   退出
  20. 企业"字段 至 "企业"字段 之间 或许会有很多行,  示例中只是尽量缩短没影响的行
  21. if 如果遇到有"企业"字段 与 "企业"字段 之间的名称不相同,  且它们中间没有 "退出"字段, 则需要添加插入 "退出"字段行,  如果他们字段之间有了 "退出"字段, 则跳过忽略,  日期时间填补请使用有"企业"字段的上一行日期时间
  22. if 如果有"企业"字段的行  一直至有 "退出"字段行中, 它们名称仍然都是相同的,  ,  则不做任何动作
  23. 名称有可能会使用某些字符号,    希望可尽量支持多些名称字符
  24. PowerShell  awk bat
  25. 或许 可以将 ">"  看成分隔符处理吧
  26. >b.txt
  27. 19:37:30 August 16 2023>   企业 名称:优 美 利 A
  28. 19:37:31 August 16 2023>   ++++
  29. 19:37:31 August 16 2023>   退出
  30. 19:37:32 August 16 2023>   企业 名称:利海 B
  31. 19:37:33 August 16 2023>    +
  32. 19:37:33 August 16 2023>    退出
  33. 19:37:34 August 16 2023>   企业 名称:利海 01:C (A)
  34. 19:37:35 August 16 2023>   +
  35. 19:37:35 August 16 2023>   退出
  36. 19:37:36 August 16 2023>   企业 名称:海
  37. 19:37:39 August 16 2023>   退出
  38. 20:37:30 August 16 2023>   企业 名称:利海 B
  39. 20:39:30 August 16 2023>   企业 名称:利海 B
  40. 20:38:31 August 16 2023>   退出
  41. 20:37:30 August 16 2023>   企业 名称:利
  42. 20:39:30 August 16 2023>   +
  43. 20:39:30 August 16 2023>   +
  44. 20:39:30 August 16 2023>   +
  45. 20:39:30 August 16 2023>   退出
  46. 20:39:30 August 16 2023>   企业 名称:利海 B
  47. 20:38:31 August 16 2023>   退出
复制代码

回复 44# qixiaobin0715


   Yeah,   很灵巧的解决某些原字符问题 , 和18楼哥哥的都能正确完成

此题终结,  谢谢以上参与题目的所有朋友

TOP

本帖最后由 qixiaobin0715 于 2023-8-26 09:48 编辑

回复 37# 娜美
实际上好好看看34楼链接的帖子,就能解决37楼的问题。
总的原则是在setlocal和endlocal之外设置变量,在其内部使用设置的变量。
33楼和37楼其实是同一类的问题,只不过前者是显示,后者是比较,所以解决的方法也类似。
我已把42楼的代码修改,看看是否能解决你的问题。

TOP

回复 42# qixiaobin0715


   OK 了

TOP

本帖最后由 qixiaobin0715 于 2023-8-26 09:31 编辑

回复 41# 娜美
前面让你提供真实文本,样本不典型。修改了输出样式,这样看起来更一致:
  1. @echo off
  2. (for /f "tokens=1* delims=>" %%i in (a.txt) do (
  3.     set m=
  4.     for /f %%x in ("%%j") do (
  5.         if "%%x"=="企业" (
  6.             set "str1=%%j"
  7.             setlocal enabledelayedexpansion
  8.             if not "!str1!"=="!str2!" (
  9.                 if defined n (
  10.                     echo,!Times!^>   `退出
  11.                     echo,
  12.                 )
  13.             )
  14.             endlocal
  15.             set n=0
  16.             set "str2=%%j"
  17.         ) else if "%%x"=="退出" (
  18.             set m=1
  19.             set n=
  20.         )
  21.     )
  22.     if not "%%j"=="" (echo,%%i^>%%j) else echo,%%i
  23.     if defined m echo,
  24.     set "Times=%%i"
  25. ))>b.txt
  26. if %n% equ 0 echo,%Times%^>   `退出>>b.txt
  27. (for /f "delims=:" %%i in ('findstr /r /n "`退出" b.txt') do echo,%%i)>AddedLines.txt
  28. pause
复制代码
再试试看看。

TOP

回复 40# qixiaobin0715


   哦哦,  代码会改变一些与之没有关系的行在每1行后面都会加上 ">"    虽然没有多大问题,  但不应该影响或者改变与之没有那些关系的行,  

  1. 20:39:30 August 16 2023>   企业 名称:利海 B
  2. Intel graphics 5.2.0.10094
  3. 检测到的设备:  8 CPUs, 1 NVidia GPU, 1 Intel Graphics
  4. 系统目录 - C:\Windows\SYSNATIVE
复制代码

TOP

看到在12楼你有显示新增行的需求,最简单的办法是在新增行中做一个标记,比如在“退出”前面加个不常用的符号,如“`退出”,使用findstr /n命令查找这些新增行。缺点是输出结果中,新增行多出了一个符号。
以36楼的代码为例:
1.将代码第8、24行中的“退出”改为“`退出”。
2.在pause前一行增加一行代码:
  1. (for /f "delims=:" %%i in ('findstr /r /n "`退出" b.txt') do echo,%%i)>AddedLines.txt
复制代码

TOP

回复 38# qixiaobin0715 嗯嗯 好吧

TOP

那是没有考虑含有“企业”的行的情况,请不要纠结这个问题了。还是以实际存在的问题为主,否则每次写代码都要面面俱到,就会出现代码复杂,效率低下的问题。

TOP

回复 36# qixiaobin0715


  确实可以解决原样输出的问题哦 但如果 名称 部分特殊字符发现一律会当不相同处理, 会插入一行,   特别是含有 "!" 字符,    似乎是识别字符不够多

为了测验,  我偿试举了一些含有 "!" 字符 例试试
20:37:30 August 16 2023> 企业 名称:美!
20:37:30 August 16 2023> 企业 名称:美!


20:37:30 August 16 2023> 企业 名称:美
20:37:30 August 16 2023> 企业 名称:美


多特殊字符, 批处理不知道能够支持多少
  1. 20:37:30 August 16 2023>   企业 名称:美` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP
  2. 20:39:30 August 16 2023> ! ` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP
  3. 20:37:30 August 16 2023>   企业 名称:美` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP
  4. 20:39:30 August 16 2023> ! ` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP
  5. 20:37:30 August 16 2023>   企业 名称:美` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP
  6. 20:39:30 August 16 2023> * ` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP
  7. 20:39:30 August 16 2023> ? ` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP
  8. 20:37:30 August 16 2023>   企业 名称:美` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ "0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP
  9. 20:39:30 August 16 2023>   +
  10. 20:39:30 August 16 2023>   企业 名称:利海 B
复制代码

TOP

本帖最后由 qixiaobin0715 于 2023-8-24 13:21 编辑

想了想,楼上说的有点太绝对,好像可以在特定位置添加setlocal和endlocal组合来实现部分特殊字符显示原样输出的问题,代码未测试:
  1. @echo off
  2. (for /f "tokens=1* delims=>" %%i in (a.txt) do (
  3.     for /f %%x in ("%%j") do (
  4.         if "%%x"=="企业" (
  5.             setlocal enabledelayedexpansion
  6.             if not "%%j"=="!str!" (
  7.                 if "!n!"=="0" (
  8.                     echo,!Times!^>   退出
  9.                     echo,
  10.                 ) else if defined n (
  11.                     echo,
  12.                 )
  13.             )
  14.             endlocal
  15.             set n=0
  16.             set "str=%%j"
  17.         ) else if "%%x"=="退出" (
  18.             set n=1
  19.         )
  20.     )
  21.     echo,%%i^>%%j
  22.     set "Times=%%i"
  23. ))>b.txt
  24. if %n% equ 0 echo,%Times%^>   退出>>b.txt
  25. pause
复制代码
请自行测试。

TOP

其它变量还可以想办法解决,31楼代码第22行变量Times的设置不好处理,因为你要增加的“退出”那一行,要使用上一行的时间。

TOP

回复 33# 娜美
出现这种情况的原因见 http://www.bathome.net/thread-11193-1-1.html
但是我觉得在这里for循环体内使用setlocal和endlocal不适合,因为要兼顾到当前行上面的若干行,endlocal后,前面所有设置的变量都消失了。还是考虑其它程序或方法。

TOP

本帖最后由 娜美 于 2023-8-23 23:32 编辑

回复 31# qixiaobin0715


     检测发现会改变原本某些行内容, 特别是有 "!" 号行   问题是似乎不支持在 ">" 之后某些字符, 但无论如何, 与之没有关系的这些行不应该会受到影响或强制改变他原样

用符号测验原来会吃掉一大半字符
20:39:30 August 16 2023> ! ++
20:39:30 August 16 2023>   ` ~!@#$%^&*()_+=-{}|[]\:;'<>?,./ " 用符号测验出原因了, 原来是会吃掉在 ">" 之后的一大半字符,

TOP

回复 31# qixiaobin0715


对对对, 和18楼哥哥一样,  完全正确了, 哥哥你这思路就很好嘛,    给代码赋予了智慧, 就像Ai一样灵活地工作,,批处理还能很快不到5分钟

TOP

返回列表