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

[问题求助] PowerShell同步修改特定行的序号并排序

[复制链接]
发表于 2022-12-2 09:43:35 | 显示全部楼层 |阅读模式

这个贴子和右边链接里的情况有很多相似之处 http://www.bathome.net/thread-64532-1-1.html
下面图片左侧是要修改的文本, 右侧是处理后的文本, 文本颜色仅表示对应关系
如果下方图片显示不清, 请打开链接  i.ibb.co/Fb5Y7H2/8.png


要处理的文本分为两部分:
第1个以#bub Bub开头的行之前是第1部分【蓝框之前的内容】
之后是第2部分【蓝框中的内容】
----------------------------------------------------------------------------------------------------------------------
处理过程:

①第1部分的文本中, 如果某行中存在 :bub.BubXX 则按先后顺序修改XX的序号【XX是1至4位的数字】, 在示例中:
包含 :bub.Bub11 的行是先出现的, 则把11改为1
包含 :bub.Bub65 的行是第2出现的, 则把65改为2
其它的以此类推

②第1部分中包含 :bub.BubXX 的行 与 第2部分中 #bub.BubXX 开头的行是互相绑定的, XX需要同步修改, 在示例中:
第1部分中 :bub.Bub11 改为 :bub.Bub1 之后,  第2部分的 #bub.Bub11 要同步改为 #bub.Bub1
相互绑定的行在图中已用同种颜色标记起来了

③上面XX同步修改的同时, 把#bub.BubXX开头的行尾部的m字母后面修改成如下格式:
m + 空格 + ;; + 与其绑定的 :bub.BubXX 冒号之前的文本
在示例中:
ab :bub.Bub11 和 #bub Bub11 m 是绑定的, 同步修改后应该是
ab :bub.Bub11 改为 ab :bub.Bub1
#bub Bub11 m 改为 #bub Bub1 m ;;ab

④如果第1部分的:bub.BubXX没匹配到的#bub BubXX的行,则新建#开头的行, 在示例中:
ZZ :bub.Bub26 匹配不到#bub Bub26的行,则把26改为5之后,新建下列的行
#bub Bub5 m ;;ZZ
我是新加的

⑤最后将第2部分的内容, 按XX的先后顺序排序

注意:
上面的操作基本是在改序号和修改m字母后面的内容, 其它内容不能改动
#bub.BubXX开头的行前只保留一个空行
  1. $s= @'
  2. ab $( ) :bub.Bub11
  3. - :TA_Fbv "T " * $q$\m.co
  4. 中国 ac :bub.Bub65 * a.b
  5. >windows - china * cdef
  6. 小 日本 japen :bub.Bub10 ;;c.e
  7. |
  8. ac ${ } :bub.Bub18
  9. <
  10. ZZ :bub.Bub26


  11. #bub Bub10 m ;;1 小日本
  12. 我之前序号是10
  13.           最后是3
  14. #bub Bub


  15. #bub Bub11 m
  16. 我之前序号是11
  17.           最后是1
  18.         #bub Bub 11

  19. #bub Bub18 m ;;6
  20. 我之前序号是18
  21.           最后是4
  22. #bub Bub 4

  23. #bub Bub65 m ;;
  24. 我之前序号是18
  25.           最后是2
  26. '@

  27. #Todo 处理代码

  28. <# 处理后的效果
  29. ab $( ) :bub.Bub1
  30. - :TA_Fbv "T " * $q$\m.co
  31. 中国 ac :bub.Bub2 * a.b
  32. >windows - china * cdef
  33. 小 日本 japen :bub.Bub3 ;;c.e
  34. |
  35. ac ${ } :bub.Bub4
  36. <
  37. ZZ :bub.Bub5

  38. #bub Bub1 m ;;ab $( )
  39. 我之前序号是11
  40.           最后是1
  41.         #bub Bub 11

  42. #bub Bub2 m ;;中国 ac
  43. 我之前序号是18
  44.           最后是2

  45. #bub Bub3 m ;;小 日本 japen
  46. 我之前序号是10
  47.           最后是3
  48. #bub Bub

  49. #bub Bub4 m ;;ac ${ }
  50. 我之前序号是18
  51.           最后是4
  52. #bub Bub 4

  53. #bub Bub5 m ;;ZZ
  54. 我是新加的
  55. #>
复制代码
发表于 2022-12-2 20:35:58 | 显示全部楼层
本帖最后由 WHY 于 2022-12-3 10:12 编辑
  1. $s = @'
  2. ab $( ) :bub.Bub11
  3. - :TA_Fbv "T " * $q$\m.co
  4. 中国 ac :bub.Bub65 * a.b
  5. >windows - china * cdef
  6. 小 日本 japen :bub.Bub10 ;;c.e
  7. |
  8. ac ${ } :bub.Bub18
  9. <
  10. ZZ :bub.Bub26


  11. #bub Bub10 m ;;1 小日本
  12. 我之前序号是10
  13.           最后是3
  14. #bub Bub


  15. #bub Bub11 m
  16. 我之前序号是11
  17.           最后是1
  18.         #bub Bub 11

  19. #bub Bub18 m ;;6
  20. 我之前序号是18
  21.           最后是4
  22. #bub Bub 4

  23. #bub Bub65 m ;;
  24. 我之前序号是18
  25.           最后是2
  26. '@

  27. $arr = [Collections.ArrayList](($s -split '(?:\r?\n)+#bub Bub\d+ m')[0] -split '\r?\n'); #上半部分
  28. $count = $arr.Count;
  29. $hash = @{};
  30. $global:n = 0;

  31. forEach( $m In [regex]::Matches($s, '(?im)^#bub Bub(\d+) m(?:(?!^#bub Bub\d+ m)[\s\S])+') ){
  32.     $key = $m.Groups[1].Value;  #数字序号
  33.     $value = $m.Groups[0].Value.Trim("`r`n");
  34.     if( !$hash.Contains($key) ){
  35.         $hash.Add( $key, $value );
  36.     }
  37. }

  38. for( $i = 0; $i -lt $count; $i++ ){
  39.     $m = $arr[$i] -match '^([^:]+):bub\.Bub(\d+)';
  40.     if( $m ){
  41.         $arr[$i] = [regex]::Replace($arr[$i], '(?i)(?<=bub\.Bub)\d+',{return (++$global:n)});
  42.         $key = $matches[2];    #数字序号
  43.         if( $hash.Contains($key) ){
  44.             $str = $hash[$key] -replace '(?<=^#bub Bub)\d+ m.*(?=\r?\n)', ('' + $global:n + ' m ;;' + $matches[1]);
  45.         }else{
  46.             $str = '#bub Bub' + $global:n + ' m ;;' + $matches[1] + "`r`n我是新来的";
  47.         }
  48.         [void]$arr.Add( "`r`n" + $str );
  49.     }
  50. }

  51. $arr
复制代码
 楼主| 发表于 2022-12-3 08:34:10 | 显示全部楼层
本帖最后由 meixi 于 2022-12-3 08:35 编辑

回复 2# WHY
多谢, 我试下面的文本, 序号没有被修改
  1. $s = @'
  2. 字式 $( ) :bub.bub1 * fincc.ic
  3. 字展 ${ } :bub.bub2 * fincc.ic
  4. -
  5. 无环 While :bub.bub3 * fincc.ic
  6. 计环 For :bub.bub4 * fincc.ic
  7. 条循 While :bub.bub5 * fincc.ic
  8. 历循 Foreach :bub.bub6 * fincc.ic
  9. -
  10. 果 if :bub.bub7 * fincc.ic
  11. 则 else :bub.bub8 * fincc.ic
  12. 否果 elseif :bub.bub9 * fincc.ic
  13. 关 switch :bub.bub10 * fincc.ic
  14. 默值 default :bub.bub11 * fincc.ic
  15. |
  16. 到 上 sub :bub.bub13 * fincc.ic
  17. 到 下 sub  :bub.bub14 * fincc.ic
  18. 转换 单 at :bub.bub15 * fincc.ic
  19. 排序 集 at :bub.bub16 * fincc.ic
  20. 排序 项 menu :bub.bub17 * fincc.ic
  21. -
  22. 建 折叠区 region :bub.bub12 * fincc.ic
  23. -
  24. >dows - Cons * fincc.ic
  25.         Fi win or conl :m "TO_F dow" * target.ico
  26.         -
  27.         Fd ac obj :EA_Mai _m * fincc.ic
  28. <

  29. #bub bub1 m
  30. _s.get
  31. _s-"$("
  32. _s+")"
  33. _s.set

  34. #bub bub2 m
  35. _s.get
  36. _s-"${"
  37. _s+"}"
  38. _s.set
  39. '@
复制代码
发表于 2022-12-3 10:10:33 | 显示全部楼层
回复 3# meixi


    这个样本与顶楼的样本有什么区别,你自己做比较没?
这个样本中 bub.bub 与 #bub bub 是小写,而顶楼给的样本包含大写。
顶楼给出的样本必须具有代表性,改来改去谁都会烦。
发表于 2022-12-3 10:13:22 | 显示全部楼层
回复 3# meixi


    已修改
发表于 2022-12-3 10:27:03 | 显示全部楼层
本帖最后由 5i365 于 2022-12-3 10:50 编辑

回复 4# WHY

多谢指出, 实在不好意思, 描述中忘提了, bub 和Bub 不区分大小写
原来 -match 默认不区分大小写

但 [regex]::Matches 是区分大小写的, 学习了
发表于 2022-12-3 10:43:29 | 显示全部楼层
本帖最后由 5i365 于 2022-12-3 10:45 编辑

回复 5# WHY

$s = [io.file]::ReadAllText("C:\Users\Administrator\Desktop\1.txt")
[io.file]::WriteAllLines("C:\Users\Administrator\Desktop\1_ok.txt", $arr)


我把要处理文本用上面的代码外置了,
处理后, 原#开头的行, 后面的换行符变了
发表于 2022-12-3 11:36:49 | 显示全部楼层
本帖最后由 WHY 于 2022-12-3 11:38 编辑

回复 7# 5i365


    确实,第53行这样改:
  1. $str = $hash[$key] -replace '(?<=^#bub Bub)\d+ m[^\r\n]*', ('' + $global:n + ' m ;;' + $matches[1]);
复制代码
-replace替换运算符中,"."默认可以匹配到\r
发表于 2022-12-3 11:40:11 | 显示全部楼层
回复 8# WHY

多谢指教, 惭愧, 对复杂的正则,一看就晕, 先收藏了
发表于 2022-12-3 12:15:07 | 显示全部楼层
回复 8# WHY

大侠, 不太明白, .在replace中如果不加(?s)不能匹配到换行吧, 例如下面的代码

  1. $s = @'
  2. 日本

  3. '@
  4. $s -replace '.+人', '外国人' #.没有匹配到换行符

  5. $s -replace '(?s).+人','外国人' #.匹配到了换行符
复制代码
发表于 2022-12-3 12:57:54 | 显示全部楼层
回复 10# 5i365


    你要是对正则感兴趣,建议你多看看MS官方文档。
https://learn.microsoft.com/zh-c ... regular-expressions
网上关于正则的教程良莠不齐,有的甚至是错误的。

多行模式:修改 ^ 和 $ 的行为,^可以匹配每行的开头,$可以匹配\n(不能匹配\r\n)
单行模式:修改 . 的行为(默认情况下,"."匹配除\n以外的任意字符),可以匹配任意字符,等同于[\s\S]
发表于 2022-12-3 13:20:14 | 显示全部楼层
回复 11# WHY
多谢大侠指导,
那默认情况下, 不加  (?s)  或  (?m)

^ 和 $  还有 .


是怎么个匹配情况?  
发表于 2022-12-3 18:40:58 | 显示全部楼层
11楼的链接你打开过没有?答案就在里面。
https://learn.microsoft.com/zh-c ... ons#default-options
发表于 2022-12-3 19:55:27 | 显示全部楼层
回复 13# WHY

多谢,
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-3-16 22:03 , Processed in 0.018956 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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