arrays - PowerShell 逐行读取文件,正则表达式每行并将项目存储在数组中
问题描述
PowerShell的新手..我正在尝试逐行读取文件并将信息正则表达式转换为2个数组,以便以后可以使用这些数组进行更多处理。
我的文件的每一行看起来像这样,有数千行......
Car 1FMZU77E22UC18440 Honda Civic
Car SCBCR63W55C024793 GM Colorado
我需要将 VIN 号存储到 data1 数组中,并将汽车模型存储到 data2 数组中。car 栏和 VIN 号栏之间总是有 3 个空格;VIN 号栏和车型栏之间有 5 个空格。数据的长度不同,但空格用作分隔符。
我在 VIN 列的正则表达式之间的外观是 (?<=\s\s\s).*?(?=\s\s\s\s\s)
我在这里尝试了解决方案,但不确定如何将其存储到数组中 -在 PowerShell 中逐行读取文件
foreach($line in Get-Content myfile.txt) {
if($line -match $regex){
$data1 += $line.matches.value
}
}
我的 data1 数组是空的。我怎样才能做到这一点?谢谢。
编辑:第三列之后没有空格。我的 data2 数组的正则表达式将在后面 (?<=\s\s\s\s\s)。不确定它是否有效,因为我还不能存储我的数据。我知道我的正则表达式来自 c#...不确定它是否适用于 PowerShell。
解决方案
如果没有一些真实(模拟)数据,我认为最好不要使用正则表达式。此外,这可以通过将其视为 CSV 来大大简化。
首先进行此测试,其他人也可以尝试,我们将制作一个示例文件
$tempfile = New-TemporaryFile
$data = @'
1111 xxxx yyyyyyyyyyyyyyyy 2222 zzzz wwwwwww
3333 aaaa bbbbbbbbbbbbbbbb 4444 cccc ddddddd
'@ | Set-Content $tempfile -Encoding utf8
接下来,我们在用逗号替换空格的同时阅读信息。如果您的数据有空格,那么这当然需要调整或不使用,具体取决于。
(Get-Content $tempfile) -replace '\s+',','
1111,xxxx,yyyyyyyyyyyyyyyy,2222,zzzz,wwwwwww
3333,aaaa,bbbbbbbbbbbbbbbb,4444,cccc,ddddddd
现在我们知道我们的数据是正确的,在指定标题的同时导入为 CSV。您可以提供有意义的标题,因为您知道信息是什么。
(Get-Content $tempfile) -replace '\s+',',' | ConvertFrom-Csv -Header a,b,c,d,e,f
a : 1111
b : xxxx
c : yyyyyyyyyyyyyyyy
d : 2222
e : zzzz
f : wwwwwww
a : 3333
b : aaaa
c : bbbbbbbbbbbbbbbb
d : 4444
e : cccc
f : ddddddd
如果您只想要某些列,只需选择那些。
(Get-Content $tempfile) -replace '\s+',',' |
ConvertFrom-Csv -Header a,b,c,d,e,f | Select b,c,e,f -OutVariale data
b c e f
- - - -
xxxx yyyyyyyyyyyyyyyy zzzz wwwwwww
aaaa bbbbbbbbbbbbbbbb cccc ddddddd
现在相应地分配它
$data | select b,e -OutVariable data1
b e
- -
xxxx zzzz
aaaa cccc
$data | select c,f -OutVariable data2
c f
- -
yyyyyyyyyyyyyyyy wwwwwww
bbbbbbbbbbbbbbbb ddddddd
编辑
你有意义的数据改变了我的建议。也很好奇额外的列在哪里,因为它不像你最初展示的那样。根据您显示的数据,我有三种不同的选择。
同样,从一些示例数据开始
$tempfile = New-TemporaryFile
@'
Car 1FMZU77E22UC18440 Honda CiviC
Car SCBCR63W55C024793 GM Colorado
Truck SZXYR63W55C165487 GM some model
'@ | Set-Content $tempfile -Encoding utf8
选项 1 - ConvertFrom-String
ConvertFrom-String 可以根据您作为“训练”数据提供的模板解析数据。
$template = @'
{Type*:abc} {VIN:ABCDEFGH123456789} {Model:some model}
{Type*:abcde} {VIN:sample} {Model:a some model}
'@
现在我们应用模板。使其逐行优于正则表达式的一方面是您可以使用-Raw
非常快的获取内容的快速参数。
get-content $tempfile -Raw |
ConvertFrom-String -TemplateContent $template -OutVariable data
Type VIN Model
---- --- -----
Car 1FMZU77E22UC18440 Honda CiviC
Car SCBCR63W55C024793 GM Colorado
Truck SZXYR63W55C165487 GM some model
如果您不需要该类型,请忽略它。将其设置为您的变量,例如
$data1,$data2 = $data.vin,$data.model
变量的内容$data1
和$data2
$data2
Honda CiviC
GM Colorado
GM some model
$data1
1FMZU77E22UC18440
SCBCR63W55C024793
SZXYR63W55C165487
选项 2 - 正则表达式 Get-Content / 逐行
Get-Content $tempfile | foreach {
if($_ -match '(?<=[\s]{3})(\w*)[\s]{5}(.*)$')
{
[PSCustomObject]@{
Model = $matches.2
VIN = $matches.1
}
}
}
再次根据需要设置变量
$data1,$data2 = $data.vin,$data.model
选项 3 - Select-String(可能更接近选项 1 的速度)
Select-String -path $tempfile -Pattern '(?<=[\s]{3})(\w*)[\s]{5}(.+)' -AllMatches | ForEach {
$_.Matches | foreach {
[PSCustomObject]@{
Model = $_.groups[2].value
VIN = $_.groups[1].value
}
}
} -OutVariable data