Parsing 通过Powershell解析和更改系统的输出
最初我必须声明,到目前为止,我对powershell几乎没有经验。以前的系统为我生成了错误的输出。所以我想用PowerShell来改变这一点。从系统中,我得到如下输出:Parsing 通过Powershell解析和更改系统的输出,parsing,powershell,awk,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^
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')
$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'
当您查看它时,每一行都有一个起始部分(TEST1^^^^9999^^^^^^^^),后跟a1到a-n元组(例如:Y^^^^^^不在^^^^^^('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')
因此,元组应每行打印一次,起始部分附在前面
我的解决方法是,但是到目前为止,我还不了解如何处理不确定数量的元组,以及如何重复起始块
我提前非常感谢你的帮助 将任意长度的字符串记录解析为行记录非常容易出错。一个简单的解决方案是逐行处理数据并创建输出 下面是如何处理单行的简单示例。处理整个输入文件和编写输出对于读者来说是一个微不足道的练习
$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')
将任意长度的字符串记录解析为行记录非常容易出错。一个简单的解决方案是逐行处理数据并创建输出 下面是如何处理单行的简单示例。处理整个输入文件和编写输出对于读者来说是一个微不足道的练习
$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+',?)+\))\^?",'$1'
$j += 1
if($j -eq 3) {
write-host $heading$line
$line = ""
$j = 0
}
}
}
数据看起来非常规则,因此您可以使用
|
作为分隔符循环数据,并在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+',?)+\))\^?",'$1'
$j += 1
if($j -eq 3) {
write-host $heading$line
$line = ""
$j = 0
}
}
}
我将在
^ | ^
处拆分行,并在循环中重新组合结果数组的字段。大概是这样的:
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')
$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'
我将在
^ | ^
处拆分行,并在循环中重新组合结果数组的字段。大概是这样的:
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')
$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'
哇,谢谢你的努力,我会试试这个,然后回来找你。对于初学者,如何在txt文件中用自动抓取第一行来替换第1行?哇,谢谢你的努力,我会尝试一下,然后再回来找你。对于初学者来说,如何用自动抓取txt文件中的第一行来替换第1行?因此我需要在以后删除每个元组中的“^”?有简单的功能吗?抱歉问了这么多基本的问题,你们帮了我大忙。编辑:没关系,我说我的输出中也有它们,请看编辑。现在,当添加到
$line
时,我们可以使用正则表达式查看单元格是否为元组,并替换掉^
字符(如果数据总是以^
结尾)?我对-replace
行做了一个小小的更新,如果是这样的话,我会对它进行解释。每行的最后一个元组没有像^ | ^这样的分隔符。帮了大忙,谢谢。你救了我一夜的试错。现在,我将尝试理解它,以用于进一步的工作。多亏了其他贡献者,tooSo我以后需要删除每个元组中的“^”?有简单的功能吗?抱歉问了这么多基本的问题,你们帮了我大忙。编辑:没关系,我说我的输出中也有它们,请看编辑。现在,当添加到$line
时,我们可以使用正则表达式查看单元格是否为元组,并替换掉^
字符(如果数据总是以^
结尾)?我对-replace
行做了一个小小的更新,如果是这样的话,我会对它进行解释。每行的最后一个元组没有像^ | ^这样的分隔符。帮了大忙,谢谢。你救了我一夜的试错。现在,我将尝试理解它,以用于进一步的工作。也要感谢其他的贡献者