我有一个文本文件,其中包含每个文档集的元数据和文件路径。元数据仅在集合的开头分配,但该集合可能包含一个或多个文档。我需要为每个文档集创建一个CSV或XML输出(每个对象以“BEGIN:”开头),这样我就可以导入到另一个系统中。
我有一个PS脚本,它从文本文件中解析出每个对象,并为每个对象创建一个分隔字符串,但我认为这不是解析这些数据的最有效方法。在解析此文本文件并正确设置XML / CSV输出时,任何人都可以帮助指导我吗?
可能存在的问题
示例文本文件
BEGIN:
DocTypeName: SAMPLE
>>DocDate: 12/11/2008
Reference #: 0001122
User Name: George Washington
User Name: Martha Washington
>>IRRELEVANT DATA
...
>>FileName: [path]\761019.TIF
>>IRRELEVANT DATA
...
>>FileName: [path]\761020.TIF
BEGIN:
DocTypeName: SAMPLE
>>DocDate: 12/11/2008
Reference #: 0001123
User Name: Abe Lincoln
>>IRRELEVANT DATA
...
>>FileName: [path]\761021.TIF
>>IRRELEVANT DATA
...
>>FileName: [path]\761022.TIF
答案 0 :(得分:3)
这对你有帮助吗?
Get-Content testfile.txt -Delimiter 'BEGIN:' |
Select -Skip 1 |
foreach {
$DOC = [PSCustomObject]@{
DocTypeName = $Null
DocDate = $Null
Reference = $Null
UserName = [collections.arraylist]@()
FileName = [collections.arraylist]@()
}
Switch -Regex ($_.split("`n"))
{
'DocTypeName: (.+)' {$DOC.DocTypeName = $Matches[1];Continue}
'>>DocDate: (.+)' {$DOC.DocDate = $Matches[1];Continue}
'Reference #: (.+)' {$DOC.Reference = $Matches[1];Continue}
'User Name: (.+)' {[void]$DOC.UserName.add($Matches[1]);Continue}
'>>FileName: (.+)' {[void]$DOC.FileName.add($Matches[1]);Continue}
}
$DOC
}
答案 1 :(得分:2)
我会导入文件拆分' BEGIN:' (就像mjolinor一样),然后通过ForEach运行它,它将使用Add-Member构建一个对象,使用导入记录中的任何属性。如果您对我的代码有任何疑问,请询问。
$RawData = Get-Content testfile.txt -Delimiter 'BEGIN:' | Select -Skip 1
$Records = ForEach($Object in $RawData){
$Record=New-Object PSObject
$Object.split("`n")|Where{$_ -match "^(?:>>)?(.+?):\s*?(\S.*)?$"}|ForEach{
If([String]::IsNullOrEmpty($Record.($Matches[1]))){
Add-Member -InputObject $Record -NotePropertyName $Matches[1] -NotePropertyValue @($Matches[2])
}Else{
$Record.($Matches[1])+=$Matches[2]
}
}
$Record
}
这将为您留下一个数组$Records
,该数组包含具有输入文件提供的任何属性的对象。如果您想要的只是特定字段,那么mjolinor的解决方案可能是更好的选择。
答案 2 :(得分:0)
只是VY中新命令的一个FYI - ConvertFrom-String。这会使用一个模板来告诉命令如何解释文本,例如:
BEGIN:
DocTypeName: SAMPLE
>>DocDate: 12/11/2008
Reference #: {Reference*:{Number:0001122}
User Name: {UserNames:{UserName*:George Washington}
User Name: {UserName*:Martha Washington}}
>>IRRELEVANT DATA
...
>>FileName: {Paths:{Path*:[path]\761019.TIF}
>>IRRELEVANT DATA
...
>>FileName: {Path*:[path]\761020.TIF}}}
BEGIN:
DocTypeName: SAMPLE
>>DocDate: 12/11/2008
Reference #: {Reference*:{Number:0001123}
User Name: {UserNames:{UserName*:Abe Lincoln}}
>>IRRELEVANT DATA
...
>>FileName: {Paths:{Path*:[path]\761021.TIF}
>>IRRELEVANT DATA
...
>>FileName: {Path*:[path]\761022.TIF}}}
然后您可以抛出原始文件内容(在变量$ content中)并访问数据,如下所示:
$res = $content | cfs -TemplateFile .\template.txt
PS> $res[0].Reference.Number
0001122
PS> $res[0].Reference.UserNames.UserName.value
George Washington
Martha Washington
PS> $res[0].Reference.Paths.Path.value
[path]\761019.TIF
[path]\761020.TIF
在预览表单中使用此命令有点笨拙,因为它希望默认显示Extent
属性,我认为您只需要调试模板。