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

时间:2015-01-08 09:43:07

标签: parsing powershell awk

最初我必须声明,到目前为止我对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到一个元组(例如:Y ^ | ^ NOT IN ^ | ^(' 1'&#39 2'&#39 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,但到目前为止,我还没有理解如何处理如何处理不确定数量的元组并重复起始块的问题。

我提前感谢你的帮助!

3 个答案:

答案 0 :(得分:3)

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

$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'

答案 1 :(得分:1)

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

以下是如何处理单行的简单说明。处理整个输入文件和写入输出对于读者来说是一项微不足道的练习。

$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')

答案 2 :(得分:1)

数据看起来非常规则,所以你可以使用|作为分隔符并在3s内计算以下单元格来循环它:

$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+',?)+\))\^?",'$1'
        $j += 1
        if($j -eq 3) { 
            write-host $heading$line
            $line = ""
            $j = 0
        }
    }
}