2012-07-18 609 views
0

我对Powershell很新。只用了约2周。Powershell:解析结构化的文本文件并保存到.CSV

我有一个结构类似这样的文件:

 
Service name: WSDL 
Service ID: 14234321885 
Service resolution path: /gman/wsdlUpdte 
Serivce endpoints: 
-------------------------------------------------------------------------------- 
Service name: DataService 
Service ID: 419434324305 
Service resolution path: /widgetDate_serv/WidgetDateServ 
Serivce endpoints: 
http://servername.company.com:1012/widgetDate_serv/WidgetDateServ 
-------------------------------------------------------------------------------- 
Service name: SearchService 
Service ID: 393234543546 
Service resolution path: /ProxyServices/SearchService 
Serivce endpoints: 
http://servername.company.com:13010/Services/SearchService_5_0 
http://servername2.company.com:13010/Services/SearchService_5_0 
-------------------------------------------------------------------------------- 
Service name: Worker 
Service ID: 14187898547 
Service resolution path: /ProxyServices/Worker 
Serivce endpoints: 
http://servername.company.com:131009/Services/Worker/v9 
-------------------------------------------------------------------------------- 

我想解析文件,并有服务名称,服务标识,服务解析路径和服务端点(有时包含多个或不值)在个人柱(CSV)。

除了使用Get-Content并遍历文件,我甚至不知道从哪里开始。

任何帮助将不胜感激。 感谢

回答

1

这给一试:

  1. 81个连字符
  2. 读取文件内容作为一个字符串
  3. 它分割
  4. 拆分冒号字符上的每个拆分项并取最后一个数组项
  5. 创建新对象每个项目

    $pattern = '-'*81 
    $content = Get-Content D:\Scripts\Temp\p.txt | Out-String 
    $content.Split($pattern,[System.StringSplitOptions]::RemoveEmptyEntries) | Where-Object {$_ -match '\S'} | ForEach-Object { 
    
    $item = $_ -split "\s+`n" | Where-Object {$_} 
    
        New-Object PSobject -Property @{ 
         Name=$item[0].Split(':')[-1].Trim() 
         Id = $item[1].Split(':')[-1].Trim() 
         ResolutionPath=$item[2].Split(':')[-1].Trim() 
         Endpoints=$item[4..($item.Count)] 
        } | Select-Object Name,Id,ResolutionPath,Endpoints 
    } 
    
+0

你必须“硬编码”字段,并没有照顾多个URL的。 – JPBlanc 2012-07-20 15:24:59

+0

谢谢Shay, 我需要做一些修改才能修复一些错误信息,但是现在输出到控制台时效果很好。当我添加“| export-csv test.csv”时,最后一个对象(Endpoints)在实际文件中显示为“System.Object []”。我假设需要对该对象进行某些操作才能使其成为文本?我会开始使用Google,但如果您可以回复,那就太棒了。 – Bill 2012-07-20 15:38:16

+0

谢谢,根据你对另一个网站上其他人的回答计算出来。将最后一行更改为: } | Select-Object Name,Id,ResolutionPath,@ {n =“Endpoints”; e = {[string] :: join(“;”,$ _。Endpoints)}} 再次感谢您! – Bill 2012-07-20 16:01:22

1

试试这个:

Get-Content | ? { $_ -match ': ' } | % { $_ -split ': ' } | Export-Csv Test.csv; 

基本上它归结为:

  1. 获取所有文本内容作为一个数组
  2. 过滤器用于包含行 ':'
  3. 对于每行都留下来,将它分开':'
  4. 将对象数组导出到CSV文件nam ED test.csv

希望这点你在正确的方向。

注:代码未经测试。

0

这是一个通用的解析文件记录和记录记录的方法(等等),它使用功能强大的PowerShell switch指令和正则表达式以及begin(),Process(),end()函数模板。

加载它,调试它,改正它...

function Parse-Text 
{ 
    [CmdletBinding()] 
    Param 
    (
    [Parameter(mandatory=$true,ValueFromPipeline=$true)] 
    [string]$ficIn, 
    [Parameter(mandatory=$true,ValueFromPipeline=$false)] 
    [string]$ficOut 
) 

    begin 
    { 
    $svcNumber = 0 
    $urlnum = 0 
    $Service = @() 
    $Service += @{} 
    } 

    Process 
    { 
    switch -regex -file $ficIn 
    { 
     # End of a service 
     "^-+" 
     { 
     $svcNumber +=1 
     $urlnum = 0 
     $Service += @{} 
     } 
     # URL, n ones can exist 
     "(http://.+)" 
     { 
     $urlnum += 1 
     $url = $matches[1] 
     $Service[$svcNumber]["Url$urlnum"] = $url 
     } 
     # Fields 
     "(.+) (.+): (.+)" 
     { 
     $name,$value = $matches[2,3] 
     $Service[$svcNumber][$name] = $value 
     } 
    } 
    } 

    end 
    { 
    #$service[3..0] | % {New-Object -Property $_ -TypeName psobject} | Export-Csv c:\Temp\ws.csv 
    # Get all the services except the last one (empty -> the file2Parse is teerminated by ----...----) 
    $tmp = $service[0..($service.count-2)] | Sort-Object @{Expression={$_.keys.count };Descending=$true} 
    $tmp | % {New-Object -Property $_ -TypeName psobject} | Export-Csv $ficOut 
    } 
} 


Clear-Host 
Parse-Text -ficIn "c:\Développements\Pgdvlp_Powershell\Apprentissage\data\Text2Parse.txt" -ficOut "c:\Temp\ws.csc" 
cat "c:\Temp\ws.csv" 
1

使用PowerShell 5可以用美妙的命令“convertfrom字符串”

[email protected]' 
Service name: {ServiceName*:SearchService} 
Service ID: {serviceID:393234543546} 
Service resolution path: {ServicePath:/ProxyServices/SearchService} 
Serivce endpoints: 
http://{ServiceEP*:servername.company.com:13010/Services/SearchService_5_0} 
http://{ServiceEP*:servername2.tcompany.tcom:13011/testServices/SearchService_45_0} 
-------------------------------------------------------------------------------- 
Service name: {ServiceName*:Worker} 
Service ID: {serviceID:14187898547} 
Service resolution path: {ServicePath:/ProxyServices/Worker} 
Serivce endpoints: 
http://{ServiceEP*:servername3.company.com:13010/Services/SearchService} 
-------------------------------------------------------------------------------- 
Service name: {ServiceName*:WSDL} 
Service ID: {serviceID:14234321885} 
Service resolution path: {ServicePath:/gman/wsdlUpdte} 
Serivce endpoints: 
http://{ServiceEP*:servername4.company.com:13010/Services/SearchService_5_0} 
-------------------------------------------------------------------------------- 
'@ 


#explode file with template 
$listexploded=Get-Content -Path "c:\temp\file1.txt" | ConvertFrom-String -TemplateContent $template 

#export csv 
$listexploded |select *, @{N="ServiceEP";E={$_.ServiceEP.Value -join ","}} -ExcludeProperty ServiceEP | Export-Csv -Path "C:\temp\res.csv" -NoTypeInformation