我有一个固定宽度的文件,其记录格式如下
DDEDM2018890 19960730015000010000
DDETPL015000 20150515015005010000
DDETPL015010 20150515015003010000
DDETPL015020 20150515015002010000
DDETPL015030 20150515015005010000
DDETPL015040 20150515015000010000
前 3 个字符标识记录类型,在上面的示例中,所有记录都是 DDE
类型,但文件中也有不同类型的行。
以下带有命名捕获组的正则表达式会根据我的目的解析每个记录中的相关信息(请注意,它还会过滤到 DDE
记录类型:
DDE(?<Database>\w{3})\d{2}(?<CategoryCode>\d{2})(?<CategoryId>\d{1})\d\s+\d{8}\d{3}(?<Length>\d{3})
在this excellent online parser上使用这个正则表达式
我编写了一个脚本,使用 Get-Content
、ForEach-Object
和 Select-Object
cmdlet 来转换固定宽度文件到 csv 文件中。
我想知道是否可以用单个 Select-String
cmdlet 替换 Get-Content
和 ForEach-Object
cmdlet?
#this powershell script reads fixed width file and generates a csv file of the relevant & converted values
#Prepare HashSet object for Select-Object to convert CategoryCode and append with CategoryId
$Category = @{
Name = "Category"
Expression = {
$cat = switch($_.CategoryCode)
{
"50"{"A"}
"54"{"C"}
"60"{"F"}
"66"{"I"}
"74"{"M"}
"88"{"T"}
}
$cat+$_.CategoryId
}
}
gc "C:\Path\To\File.txt" | % {
if($_ -match "DDE(?<Database>\w{3})\d{2}(?<CategoryCode>\d{2})(?<CategoryId>\d{1})\d\s+\d{8}\d{3}(?<Length>\d{3}).*$")
{
#$matches is a hashset of named capture groups, convert to object to allow Select-Object to handle hashset elements as object properties
[PSCustomObject]$matches
}
} | select Database, $Category, Length #| export-csv "AnalysisLengths.csv" -NoTypeInformation
在我完成脚本之前,我尝试使用Select-String
cmdlet,但不知道如何使用它,我相信它可以以更 Eloquent 方式达到相同的结果。 ..这就是我所拥有的:
##Could this be completed with just the Select-String commandlet instead of Get-Content+ForEach+Select-Object?
Select-String -Path "C:\Path\To\File.txt" `
-Pattern "DDE(?<Database>\w{3})\d{2}(?<CategoryCode>\d{2})(?<CategoryId>\d{1})\d\s+\d{8}\d{3}(?<Length>\d{3})" `
| Select-Object -ExpandProperty Matches
使用-ExpandProperty
应将Microsoft.PowerShell.Commands.MatchInfo
Matches
属性转换为实际的System.Text.RegularExpressions .Match
每行对象...
另请参阅Powershell Select-Object vs ForEach on Select-String results
最佳答案
这是一种方法(我并不为此感到自豪)
Select-String -Path "C:\Path\To\File.txt" -Pattern "DDE(?<Database>\w{3})\d{2}(?<CategoryCode>\d{2})(?<CategoryId>\d{1})\d\s+\d{8}\d{3}(?<Length>\d{3})" | %{New-Object -TypeName PSObject -Property @{Database=$_.matches.groups[1];CategoryCode=$_.matches.groups[2];CategoryId=$_.matches.groups[3];Length=$_.matches.groups[4]}} | export-csv "C:\Path\To\File.csv"
关于regex - 是否可以将 Get-Content、ForEach-Object string -match 替换为 Select-String cmdlet?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30419612/