Board logo

标题: [问题求助] [已解决]Powershell中定义函数可根据不同参数处理不同区域 [打印本页]

作者: meixi    时间: 2022-12-17 15:42     标题: [已解决]Powershell中定义函数可根据不同参数处理不同区域

本帖最后由 meixi 于 2022-12-21 07:41 编辑

我需要在Powershell中定义一个函数, 它可以根据不同的参数来处理文本文件中的不同区域
下面图片是一个示意图,  它标记了要处理的文本的不同区域

区域用A和B两个标记(即:一行开头的文本)来划分:
若一行以A标记的文本开头, 则是区域的开始
若一行以B标记的文本开头, 则是区域的结尾
所以上图中有两个要处理的区域, 分别是①区和②区

函数的构造如下:
函数名: GetTextArea
参数可以有3个或2个
-----------------------------------------------------------------------------------
当参数有3个时:   
函数表达式是:   GetTextArea -A "SSSS=" -B "MMM" -C $SortLine
同时存在标记参数-A和-B 例如上图中
        -A参数的值是 SSSS=
        -B参数的值是 MMM
还存在参数-C
        这个参数是一段代码段的变量名 $SortLine (代码来自下面的链接,感谢iD大佬)
        http://www.bathome.net/thread-64701-1-1.html
        它的作用是分别排序前面-A和-B两个标记所获取的区域中的文本, 即图中①区和②区的文本
函数的最后输出值, 是-C代码处理①区和②区后的文本替换原始文本后的整个文本
-----------------------------------------------------------------------------------
当参数有2个时, 分两种情况:
★情况一
函数表达式是:   GetTextArea -A "SSSS=" -C $SortLine
只有参数-A 但没有参数-B 例如上图中, 有-A参数: 值是 SSSS=
还存在参数-C
此情况下, 函数的输出值, 是-C中的代码只处理第1个-A标记之前的文本(绿框中的文本)后的内容

★情况二
函数表达式是:   GetTextArea -B "MMM" -C $SortLine
只有参数-B 但没有参数-A 例如上图中, 有-B参数: 值是 MMM
还存在参数-C
此情况下, 函数的输出值, 是参数-C中的代码只处理最后一个-B标记之后的文本(粉框中的文本)后的内容
  1. $SortLine = {
  2. $a = @(0)
  3. $s -split '\n' | %{
  4. if ($_ -match '^\D*\d+')
  5. {
  6. $a[-1] += 1
  7. $_ -replace '(?<=^\D*)\d+', ($a -join '')
  8. }
  9. else { $_ }
  10. if ($_ -match '^\s*\)') { $a += 0 }
  11. if ($_ -match '^\s*\(') { $a = $a[0 .. ($a.count - 1 - 1)] }
  12. }
  13. }
复制代码
上图中的文本测试文件
  1. @'
  2. 1 中间
  3. -
  4. 3 日
  5. -
  6. 9 韩
  7. SSSS=
  8. 1 中间
  9. -
  10. 3 日
  11. -
  12. 1 美丽
  13. MMM
  14. abc
  15. bcd
  16. abc
  17. SSSS=
  18. 6 日
  19. 9 中
  20. ) 13 好
  21. 43 日
  22. ) 43 子
  23. 02 大家
  24. 82 中
  25. (
  26. (
  27. -
  28. 1 日
  29. MMM
  30. 6 日
  31. ) 13 好
  32. 43 日
  33. ) 43 子
  34. 82 中
  35. (
  36. 43 华
  37. -
  38. 72 行人
  39. (
  40. -
  41. 1 日
  42. '@ | Out-File 1.txt -enc utf8
复制代码

作者: meixi    时间: 2022-12-17 15:51

和下面这个链接中的处理方式类似
http://www.bathome.net/viewthread.php?tid=62151&highlight=
作者: idwma    时间: 2022-12-18 20:17

  1. $SortLine = {
  2. $a = @(0)
  3. $b=$args[0] -split '\n' | %{
  4. if ($_ -match '^\D*\d+')
  5. {
  6. $a[-1] += 1
  7. $_ -replace '(?<=^\D*)\d+', ($a -join '')
  8. }
  9. else { $_ }
  10. if ($_ -match '^\s*\)') { $a += 0 }
  11. if ($_ -match '^\s*\(') { $a = $a[0 .. ($a.count - 1 - 1)] }
  12. }
  13.         $b -join "`n"
  14. }
  15. function GetTextArea($A,$B,$C,$s=(gc 1.txt) -join "`n"){
  16. if($A -and $B -and $C){[regex]::replace($s,"(?s)(?<=$A\s+)(?<AB>.*?)(?=\s+$B)",{&$C $args[0].groups['AB'].value})}
  17. elseif($A -and $C){[regex]::replace($s,"(?s)^(?<A>.*?)(?=\s*$A)",{&$C $args[0].groups['A'].value})}
  18. elseif($B -and $C){[regex]::replace($s,"(?s)(^.+$B\s+)(?<B>.*)",{$args[0].groups[1].value;&$C $args[0].groups['B'].value})}
  19. }
复制代码

作者: meixi    时间: 2022-12-19 18:28

本帖最后由 meixi 于 2022-12-19 18:53 编辑

回复 3# idwma


  多谢大佬,

不好意思, 上面描述丢了点东西, 就是定义的函数要处理的文本, 是从前面的管道流来的! 例如像下面这样的格式, 这样就完美了
在哪里看到过, 好像要在函数体内添加$input变量的处理逻辑就可以了

gc 1.txt -enc UTF8 | GetTextArea -A "SSSS=" -B "MMM" -C $SortLine | Out-File 1_ok.txt -enc UTF8

另外还发现一个小问题,
处理后的文本, 换行符都变成了LF, 只有最后一行换行符是CRLF

用notepad2打开后, 直接提示换行符不统一,
应该win下都是CRLF
作者: idwma    时间: 2022-12-19 19:48

  1. function GetTextArea($A,$B,$C){
  2. $ofs="`r`n"
  3. $s="$input"
  4. if($A -and $B -and $C){[regex]::replace($s,"(?s)(?<=$A\s+)(?<AB>.*?)(?=\s+$B)",{&$C $args[0].groups['AB'].value})}
  5. elseif($A -and $C){[regex]::replace($s,"(?s)^(?<A>.*?)(?=\s*$A)",{&$C $args[0].groups['A'].value})}
  6. elseif($B -and $C){[regex]::replace($s,"(?s)(^.+$B\s+)(?<B>.*)",{$args[0].groups[1].value+(&$C $args[0].groups['B'].value)})}
  7. }
复制代码





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