通过 Powershell 解析和更改系统的输出

Parse and change the output of a system through Powershell

首先我必须声明,到目前为止我对 Powershell 几乎没有任何经验。以前的系统为我生成了错误的输出。所以我想使用 PowerShell 来改变这一点。从系统中我得到如下所示的输出:

TEST1^|^9999^|^Y^|^NOT IN^|^('1','2','3')^|^N^|^LIKE^|^('4','5','6','7')^|^...^|^Y^|^NOT IN^|^('8','9','10','11','12')
TEST2^|^9998^|^Y^|^NOT IN^|^('4','5','6')^|^N^|^LIKE^|^('6','7','8','9')^|^...^|^Y^|^NOT IN^|^('1','2','15','16','17')^|^Y^|^NOT IN^|^('18','19','20','21','22')

看的时候,每一行都有一个起始部分(TEST1^|^9999^|^),后面跟着a1到a-n元组(例如:Y^|^NOT IN^|^('1 ','2','3')^|^).

我希望它看起来像这样:

TEST1^|^9999^|^Y^|^NOT IN^|^('1','2','3')
TEST1^|^9999^|^N^|^LIKE^|^('4','5','6','7')
TEST1^|^9999^|^Y^|^NOT IN^|^('8','9','10','11','12')
TEST2^|^9998^|^Y^|^NOT IN^|^('4','5','6')
TEST2^|^9998^|^N^|^LIKE^|^('6','7','8','9')
TEST2^|^9998^|^Y^|^NOT IN^|^('1','2','15','16','17')
TEST2^|^9998^|^Y^|^NOT IN^|^('18','19','20','21','22')

所以元组应该每行打印出来,开始部分放在前面。

我的解决方法是AWK equivalent in Powershell,但到目前为止,我对如何处理不确定数量的元组和重复起始块的问题缺乏理解。

非常感谢您的帮助!

将任意长度的字符串记录解析为行记录很容易出错。一个简单的解决方案是逐行处理数据并创建输出。

这里是如何处理单行的简单说明。处理整个输入文件和写入输出留给 reader.

作为微不足道的练习。
$s = "TEST1^|^9999^|^Y^|^NOT IN^|^('1','2','3')^|^N^|^LIKE^|^('4','5','6','7')^|^Y^|^NOT IN^|^('8','9','10','11','12')"
$t = $s.split('\)', [StringSplitOptions]::RemoveEmptyEntries)
$testNum = ([regex]::match($t[0], "(?i)(test\d+\^\|\^\d+)")).value # Hunt for 1st colum values
$t[0] = $t[0] + ')' # Fix split char remove
for($i=1;$i -lt $t.Length; ++$i) { $t[$i] = $testNum + $t[$i] + ')' } # Add 1st colum and split char remove

$t
TEST1^|^9999^|^Y^|^NOT IN^|^('1','2','3')
TEST1^|^9999^|^N^|^LIKE^|^('4','5','6','7')
TEST1^|^9999^|^Y^|^NOT IN^|^('8','9','10','11','12')

数据看起来很规则,因此您可以使用 | 作为分隔符对其进行循环,并在 3 秒内计算以下单元格:

$data = @"
TEST1^|^9999^|^Y^|^NOT IN^|^('1','2','3')^|^N^|^LIKE^|^('4','5','6','7')^|^Y^|^NOT IN^|^('8','9','10','11','12')
TEST2^|^9998^|^Y^|^NOT IN^|^('4','5','6')^|^N^|^LIKE^|^('6','7','8','9')^|^Y^|^NOT IN^|^('1','2','15','16','17')^|^Y^|^NOT IN^|^('18','19','20','21','22')
"@

$data.split("`n") | % { 
    $ds = $_.split("|")
    $heading = "$($ds[0])|$($ds[1])"
    $j = 0

    for($i = 2; $i -lt $ds.length; $i += 1) {
        $line += "|$($ds[$i])" -replace "\^(\((?:'\d+',?)+\))\^?",''
        $j += 1
        if($j -eq 3) { 
            write-host $heading$line
            $line = ""
            $j = 0
        }
    }
}

我将在 ^|^ 处拆分行并在循环中重新组合结果数组的字段。像这样:

$sp = '^|^'

Get-Content 'C:\path\to\input.txt' | % {
  $a = $_ -split [regex]::Escape($sp)
  for ($i=2; $i -lt $a.length; $i+=3) {
    "{0}$sp{1}$sp{2}$sp{3}$sp{4}" -f $a[0,1,$i,($i+1),($i+2)]
  }
} | Set-Content 'C:\path\to\output.txt'