首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取半结构化文本文件

读取半结构化文本文件
EN

Stack Overflow用户
提问于 2015-01-08 22:03:14
回答 3查看 197关注 0票数 0

我有一个文本文件,它包含每个文档集的元数据和文件路径。元数据只在集合的开头分配,但是集合可能包含一个或多个文档。我需要为每个文档集创建一个CSV或XML输出(每个对象都以“start:”开头),这样我就可以导入到另一个系统中。

我有一个PS脚本,它从文本文件中解析出每个对象,并为每个对象创建一个分隔字符串,但是我认为这不是解析这些数据的最有效的方法。在解析这个文本文件和正确设置XML/CSV输出方面,有人能帮助我朝着正确的方向前进吗?

潜在问题

  1. 对象可以有一个或多个用户名。
  2. 对象可以具有图像文件的一个或多个路径。

示例文本文件

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

发布于 2015-01-08 22:59:51

这对你有帮助吗?

代码语言:javascript
复制
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
}
票数 3
EN

Stack Overflow用户

发布于 2015-01-08 23:05:33

我会在'BEGIN:‘上导入拆分的文件(就像mjolinor一样),然后通过一个ForEach运行它,它将使用导入记录中的任何属性构建一个带有Add成员的对象。如果你对我的代码有任何疑问,请问。

代码语言:javascript
复制
$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
EN

Stack Overflow用户

发布于 2015-01-09 18:43:01

只是一个新命令的FYI在V5 -转换从-字符串。这需要一个模板,用于告诉命令如何解释文本,例如:

代码语言:javascript
复制
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中)并访问如下所示的数据:

代码语言:javascript
复制
$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属性,我认为您只需要调试模板。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27850332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档