标题: [问题求助] [已解决]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标记之后的文本(粉框中的文本)后的内容- $SortLine = {
- $a = @(0)
- $s -split '\n' | %{
- if ($_ -match '^\D*\d+')
- {
- $a[-1] += 1
- $_ -replace '(?<=^\D*)\d+', ($a -join '')
- }
- else { $_ }
- if ($_ -match '^\s*\)') { $a += 0 }
- if ($_ -match '^\s*\(') { $a = $a[0 .. ($a.count - 1 - 1)] }
- }
- }
复制代码
上图中的文本测试文件- @'
- 1 中间
- -
- 3 日
- -
- 9 韩
- SSSS=
- 1 中间
- -
- 3 日
- -
- 1 美丽
- MMM
- abc
- bcd
- abc
- SSSS=
- 6 日
- 9 中
- ) 13 好
- 43 日
- ) 43 子
- 02 大家
- 82 中
- (
- (
- -
- 1 日
- MMM
- 6 日
- ) 13 好
- 43 日
- ) 43 子
- 82 中
- (
- 43 华
- -
- 72 行人
- (
- -
- 1 日
- '@ | 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
- $SortLine = {
- $a = @(0)
- $b=$args[0] -split '\n' | %{
- if ($_ -match '^\D*\d+')
- {
- $a[-1] += 1
- $_ -replace '(?<=^\D*)\d+', ($a -join '')
- }
- else { $_ }
- if ($_ -match '^\s*\)') { $a += 0 }
- if ($_ -match '^\s*\(') { $a = $a[0 .. ($a.count - 1 - 1)] }
- }
- $b -join "`n"
- }
-
- function GetTextArea($A,$B,$C,$s=(gc 1.txt) -join "`n"){
- if($A -and $B -and $C){[regex]::replace($s,"(?s)(?<=$A\s+)(?<AB>.*?)(?=\s+$B)",{&$C $args[0].groups['AB'].value})}
- elseif($A -and $C){[regex]::replace($s,"(?s)^(?<A>.*?)(?=\s*$A)",{&$C $args[0].groups['A'].value})}
- elseif($B -and $C){[regex]::replace($s,"(?s)(^.+$B\s+)(?<B>.*)",{$args[0].groups[1].value;&$C $args[0].groups['B'].value})}
- }
复制代码
作者: 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
- function GetTextArea($A,$B,$C){
- $ofs="`r`n"
- $s="$input"
- if($A -and $B -and $C){[regex]::replace($s,"(?s)(?<=$A\s+)(?<AB>.*?)(?=\s+$B)",{&$C $args[0].groups['AB'].value})}
- elseif($A -and $C){[regex]::replace($s,"(?s)^(?<A>.*?)(?=\s*$A)",{&$C $args[0].groups['A'].value})}
- elseif($B -and $C){[regex]::replace($s,"(?s)(^.+$B\s+)(?<B>.*)",{$args[0].groups[1].value+(&$C $args[0].groups['B'].value)})}
- }
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |