标题: [问题求助] PowerShell同步修改特定行的序号并排序 [打印本页]
作者: meixi 时间: 2022-12-2 09:43 标题: PowerShell同步修改特定行的序号并排序
这个贴子和右边链接里的情况有很多相似之处 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开头的行前只保留一个空行- $s= @'
- ab $( ) :bub.Bub11
- - :TA_Fbv "T " * $q$\m.co
- 中国 ac :bub.Bub65 * a.b
- >windows - china * cdef
- 小 日本 japen :bub.Bub10 ;;c.e
- |
- ac ${ } :bub.Bub18
- <
- ZZ :bub.Bub26
-
-
- #bub Bub10 m ;;1 小日本
- 我之前序号是10
- 最后是3
- #bub Bub
-
-
- #bub Bub11 m
- 我之前序号是11
- 最后是1
- #bub Bub 11
-
- #bub Bub18 m ;;6
- 我之前序号是18
- 最后是4
- #bub Bub 4
-
- #bub Bub65 m ;;
- 我之前序号是18
- 最后是2
- '@
-
- #Todo 处理代码
-
- <# 处理后的效果
- ab $( ) :bub.Bub1
- - :TA_Fbv "T " * $q$\m.co
- 中国 ac :bub.Bub2 * a.b
- >windows - china * cdef
- 小 日本 japen :bub.Bub3 ;;c.e
- |
- ac ${ } :bub.Bub4
- <
- ZZ :bub.Bub5
-
- #bub Bub1 m ;;ab $( )
- 我之前序号是11
- 最后是1
- #bub Bub 11
-
- #bub Bub2 m ;;中国 ac
- 我之前序号是18
- 最后是2
-
- #bub Bub3 m ;;小 日本 japen
- 我之前序号是10
- 最后是3
- #bub Bub
-
- #bub Bub4 m ;;ac ${ }
- 我之前序号是18
- 最后是4
- #bub Bub 4
-
- #bub Bub5 m ;;ZZ
- 我是新加的
- #>
复制代码
作者: WHY 时间: 2022-12-2 20:35
本帖最后由 WHY 于 2022-12-3 10:12 编辑
- $s = @'
- ab $( ) :bub.Bub11
- - :TA_Fbv "T " * $q$\m.co
- 中国 ac :bub.Bub65 * a.b
- >windows - china * cdef
- 小 日本 japen :bub.Bub10 ;;c.e
- |
- ac ${ } :bub.Bub18
- <
- ZZ :bub.Bub26
-
-
- #bub Bub10 m ;;1 小日本
- 我之前序号是10
- 最后是3
- #bub Bub
-
-
- #bub Bub11 m
- 我之前序号是11
- 最后是1
- #bub Bub 11
-
- #bub Bub18 m ;;6
- 我之前序号是18
- 最后是4
- #bub Bub 4
-
- #bub Bub65 m ;;
- 我之前序号是18
- 最后是2
- '@
-
- $arr = [Collections.ArrayList](($s -split '(?:\r?\n)+#bub Bub\d+ m')[0] -split '\r?\n'); #上半部分
- $count = $arr.Count;
- $hash = @{};
- $global:n = 0;
-
- forEach( $m In [regex]::Matches($s, '(?im)^#bub Bub(\d+) m(?:(?!^#bub Bub\d+ m)[\s\S])+') ){
- $key = $m.Groups[1].Value; #数字序号
- $value = $m.Groups[0].Value.Trim("`r`n");
- if( !$hash.Contains($key) ){
- $hash.Add( $key, $value );
- }
- }
-
- for( $i = 0; $i -lt $count; $i++ ){
- $m = $arr[$i] -match '^([^:]+):bub\.Bub(\d+)';
- if( $m ){
- $arr[$i] = [regex]::Replace($arr[$i], '(?i)(?<=bub\.Bub)\d+',{return (++$global:n)});
- $key = $matches[2]; #数字序号
- if( $hash.Contains($key) ){
- $str = $hash[$key] -replace '(?<=^#bub Bub)\d+ m.*(?=\r?\n)', ('' + $global:n + ' m ;;' + $matches[1]);
- }else{
- $str = '#bub Bub' + $global:n + ' m ;;' + $matches[1] + "`r`n我是新来的";
- }
- [void]$arr.Add( "`r`n" + $str );
- }
- }
-
- $arr
复制代码
作者: meixi 时间: 2022-12-3 08:34
本帖最后由 meixi 于 2022-12-3 08:35 编辑
回复 2# WHY
多谢, 我试下面的文本, 序号没有被修改- $s = @'
- 字式 $( ) :bub.bub1 * fincc.ic
- 字展 ${ } :bub.bub2 * fincc.ic
- -
- 无环 While :bub.bub3 * fincc.ic
- 计环 For :bub.bub4 * fincc.ic
- 条循 While :bub.bub5 * fincc.ic
- 历循 Foreach :bub.bub6 * fincc.ic
- -
- 果 if :bub.bub7 * fincc.ic
- 则 else :bub.bub8 * fincc.ic
- 否果 elseif :bub.bub9 * fincc.ic
- 关 switch :bub.bub10 * fincc.ic
- 默值 default :bub.bub11 * fincc.ic
- |
- 到 上 sub :bub.bub13 * fincc.ic
- 到 下 sub :bub.bub14 * fincc.ic
- 转换 单 at :bub.bub15 * fincc.ic
- 排序 集 at :bub.bub16 * fincc.ic
- 排序 项 menu :bub.bub17 * fincc.ic
- -
- 建 折叠区 region :bub.bub12 * fincc.ic
- -
- >dows - Cons * fincc.ic
- Fi win or conl :m "TO_F dow" * target.ico
- -
- Fd ac obj :EA_Mai _m * fincc.ic
- <
-
- #bub bub1 m
- _s.get
- _s-"$("
- _s+")"
- _s.set
-
- #bub bub2 m
- _s.get
- _s-"${"
- _s+"}"
- _s.set
- '@
复制代码
作者: WHY 时间: 2022-12-3 10:10
回复 3# meixi
这个样本与顶楼的样本有什么区别,你自己做比较没?
这个样本中 bub.bub 与 #bub bub 是小写,而顶楼给的样本包含大写。
顶楼给出的样本必须具有代表性,改来改去谁都会烦。
作者: WHY 时间: 2022-12-3 10:13
回复 3# meixi
已修改
作者: 5i365 时间: 2022-12-3 10:27
本帖最后由 5i365 于 2022-12-3 10:50 编辑
回复 4# WHY
多谢指出, 实在不好意思, 描述中忘提了, bub 和Bub 不区分大小写
原来 -match 默认不区分大小写
但 [regex]::Matches 是区分大小写的, 学习了
作者: 5i365 时间: 2022-12-3 10:43
本帖最后由 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)
我把要处理文本用上面的代码外置了,
处理后, 原#开头的行, 后面的换行符变了
作者: WHY 时间: 2022-12-3 11:36
本帖最后由 WHY 于 2022-12-3 11:38 编辑
回复 7# 5i365
确实,第53行这样改:- $str = $hash[$key] -replace '(?<=^#bub Bub)\d+ m[^\r\n]*', ('' + $global:n + ' m ;;' + $matches[1]);
复制代码
-replace替换运算符中,"."默认可以匹配到\r
作者: 5i365 时间: 2022-12-3 11:40
回复 8# WHY
多谢指教, 惭愧, 对复杂的正则,一看就晕, 先收藏了
作者: 5i365 时间: 2022-12-3 12:15
回复 8# WHY
大侠, 不太明白, .在replace中如果不加(?s)不能匹配到换行吧, 例如下面的代码
- $s = @'
- 日本
- 人
- '@
- $s -replace '.+人', '外国人' #.没有匹配到换行符
-
- $s -replace '(?s).+人','外国人' #.匹配到了换行符
复制代码
作者: WHY 时间: 2022-12-3 12:57
回复 10# 5i365
你要是对正则感兴趣,建议你多看看MS官方文档。
https://learn.microsoft.com/zh-c ... regular-expressions
网上关于正则的教程良莠不齐,有的甚至是错误的。
多行模式:修改 ^ 和 $ 的行为,^可以匹配每行的开头,$可以匹配\n(不能匹配\r\n)
单行模式:修改 . 的行为(默认情况下,"."匹配除\n以外的任意字符),可以匹配任意字符,等同于[\s\S]
作者: 5i365 时间: 2022-12-3 13:20
回复 11# WHY
多谢大侠指导,
那默认情况下, 不加 (?s) 或 (?m)
^ 和 $ 还有 .
是怎么个匹配情况?
作者: WHY 时间: 2022-12-3 18:40
11楼的链接你打开过没有?答案就在里面。
https://learn.microsoft.com/zh-c ... ons#default-options
作者: 5i365 时间: 2022-12-3 19:55
回复 13# WHY
多谢,
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |