使用 PowerShell,在文本文件中搜索多个匹配项并对结果进行分组
With PowerShell, search a text file for multiple matches and grouping results
我不知道该怎么说。不管怎样,我有一个 "orders" 这样的文件:
Packslip 123000-01 07/16/18
ship to
add1
add2
add3
city, state
country zip
[1. item part number] [item description] [item qty]
[2. item part number] [item description] [item qty]
[3. item part number] [item description] [item qty]
Packslip 321001-01 07/16/18
ship to
add1
add2
add3
city, state
country zip
[1. item part number] [item description] [item qty]
每个订单都从 "Packslip" 开头的行开始。
每个订单可以有任意数量的商品。
我想从这个文本文件中得到的是这样的:
[123000-01] [item1 part number] [item qty]
[123000-01] [item2 part number] [item qty]
[123000-01] [item3 part number] [item qty]
[321001-01] [item1 part number] [item qty]
...and so on...
可以忽略方括号,在本示例中方括号仅用于帮助分隔数据元素。
使用 Get-Content
,我能够很好地获得包装 slip/order 编号(即“123001-01”),但我似乎无法弄清楚如何获得 [item零件编号] 和 [数量],以便它们与正确的订单号相关联。
我的问题是:如何搜索此文本文件并根据可变模式和可变结果对结果进行分组?
如果你没有真实的数据,但是你提供的抽象,那么写一些东西有点困难。我对您的数据做出了以下假设:
- item id不包含white-spaces,后面跟一个white-space
- 数量不含white-space,后面有一个white-space
- 装箱单编号和第一项之间的行数是固定的
如果这些假设成立,那么这应该有效:
param (
[string]$in = "example.txt",
[string]$out = "out.txt"
)
if(Test-Path $out -PathType Leaf){
Clear-Content $out
}
$packslip_regex = "Packslip.*"
$line_number = 0
foreach($line in Get-Content $in) {
if($line -match $packslip_regex){
$packslip_number = $line.Split(" ")[1]
$line_number = 0
}
if($line_number -gt 6){
$item = $line.Split(" ")
$item_id = $item[0]
$item_number = $item[$item.Count - 1]
$out_string = "$packslip_number $item_id $item_number"
$out_string | Out-File $out -Append
}
$line_number = $line_number + 1
}
我读入了包裹单编号,然后我跳过了固定数量的行,然后我读入了后面的所有行,直到我找到另一个包裹单编号。
你这样调用脚本:
.\script.ps1 -in example.txt -out output.txt
检查下一个片段。
foreach($line in Get-Content C:\packslips.dat){
if ($line -match '^Packslip\s+(?<packslip>\S+).*$') {
$packslip = $matches.packslip
} elseif ($line -match '^\d+.\s+(?<partnumber>\S+).*\b(?<itemqty>\d+)\s*$') {
"[${packslip}] [$($matches.partnumber)] [$($matches.itemqty)]"
}
}
我不知道该怎么说。不管怎样,我有一个 "orders" 这样的文件:
Packslip 123000-01 07/16/18 ship to add1 add2 add3 city, state country zip [1. item part number] [item description] [item qty] [2. item part number] [item description] [item qty] [3. item part number] [item description] [item qty] Packslip 321001-01 07/16/18 ship to add1 add2 add3 city, state country zip [1. item part number] [item description] [item qty]
每个订单都从 "Packslip" 开头的行开始。 每个订单可以有任意数量的商品。
我想从这个文本文件中得到的是这样的:
[123000-01] [item1 part number] [item qty] [123000-01] [item2 part number] [item qty] [123000-01] [item3 part number] [item qty] [321001-01] [item1 part number] [item qty] ...and so on...
可以忽略方括号,在本示例中方括号仅用于帮助分隔数据元素。
使用 Get-Content
,我能够很好地获得包装 slip/order 编号(即“123001-01”),但我似乎无法弄清楚如何获得 [item零件编号] 和 [数量],以便它们与正确的订单号相关联。
我的问题是:如何搜索此文本文件并根据可变模式和可变结果对结果进行分组?
如果你没有真实的数据,但是你提供的抽象,那么写一些东西有点困难。我对您的数据做出了以下假设:
- item id不包含white-spaces,后面跟一个white-space
- 数量不含white-space,后面有一个white-space
- 装箱单编号和第一项之间的行数是固定的
如果这些假设成立,那么这应该有效:
param (
[string]$in = "example.txt",
[string]$out = "out.txt"
)
if(Test-Path $out -PathType Leaf){
Clear-Content $out
}
$packslip_regex = "Packslip.*"
$line_number = 0
foreach($line in Get-Content $in) {
if($line -match $packslip_regex){
$packslip_number = $line.Split(" ")[1]
$line_number = 0
}
if($line_number -gt 6){
$item = $line.Split(" ")
$item_id = $item[0]
$item_number = $item[$item.Count - 1]
$out_string = "$packslip_number $item_id $item_number"
$out_string | Out-File $out -Append
}
$line_number = $line_number + 1
}
我读入了包裹单编号,然后我跳过了固定数量的行,然后我读入了后面的所有行,直到我找到另一个包裹单编号。
你这样调用脚本:
.\script.ps1 -in example.txt -out output.txt
检查下一个片段。
foreach($line in Get-Content C:\packslips.dat){
if ($line -match '^Packslip\s+(?<packslip>\S+).*$') {
$packslip = $matches.packslip
} elseif ($line -match '^\d+.\s+(?<partnumber>\S+).*\b(?<itemqty>\d+)\s*$') {
"[${packslip}] [$($matches.partnumber)] [$($matches.itemqty)]"
}
}