Powershell 导入具有特定格式的文本文件并转换为csv/generate psobject

Powershell 导入具有特定格式的文本文件并转换为csv/generate psobject,powershell,Powershell,我有一种情况,我必须读取一个日志文件,其中包含许多在过去使用out file命令生成的转储用户属性 文本的格式为: Num : 1 Property2 : Some Char Property3 : Some Text Property4 : CN=Some Text,OU=Some Text,DC=Some Text,DC=Some Text,DC

我有一种情况,我必须读取一个日志文件,其中包含许多在过去使用out file命令生成的转储用户属性

文本的格式为:

Num                        : 1
Property2                  : Some Char
Property3                  : Some Text
Property4                  : CN=Some Text,OU=Some Text,DC=Some Text,DC=Some Text,DC=Some Text,DC=net
Property5                  : Some Text
Property6                  : Some Text@Some Text.Some Text.Some Text.net
Property7                  : Some Text
Property8                  : Multiple line text
                             Multiple line text
                             Multiple line text
                             Multiple line text
Property9                  : Some Char

Num                        : 2
Property2                  : Some Char
Property3                  : Some Text
Property4                  : CN=Some Text,OU=Some Text,DC=Some Text,DC=Some Text,DC=Some Text,DC=net
Property5                  : Some Text
Property6                  : Some Text@Some Text.Some Text.Some Text.net
Property7                  : Some Text
Property8                  : Multiple line text
                             Multiple line text
                             Multiple line text
                             Multiple line text
Property9                  : Some Char

是否有一种方法可以导入它并具有结构属性值。像PSobject之类的东西?我必须根据条件在其多行属性(属性8)中搜索每个用户,并仅提取符合此条件的用户。

若要解析此内容并在CSV文件中设置所需格式,我建议使用一个有序的哈希表来解析文件的内容,然后将其转换为PsCustomObjects数组,以输出带有标题的文件

# create an ordered Hashtable to store the results
$hash = [ordered]@{}
foreach ($line in (Get-Content -Path 'D:\Test\TheInputLOgFile.txt')) {
    if ($line.IndexOf(':') -gt 0) {
        $name, $value = $line -split '\s*:\s*', 2
        $hash[$name] = $value
    }
    else {
        $hash[$name] += [Environment]::NewLine + $line.Trim()
    }
}
如果您直接输出散列,您将得到

$hash | Format-List
双击此文件以在Excel中打开(并将单元格对齐方式设置为)时,其外观如下所示:


编辑

如果输入文件中有更多项,如新示例中所示,则其中的每个数据块都需要一个额外的循环

这可以按如下方式完成:

# split the content of the file in text blocks on the double NewLine
$blocks = (Get-Content -Path 'D:\Test\TheInputLogFile.txt' -Raw) -split '(\r?\n){2,}'
# loop through each textblock, split the lines, build and convert 
# the the Hashtable and capture the results in variable $result
$result = $blocks | ForEach-Object {
    # create an ordered Hashtable to store the results
    $hash = [ordered]@{}
    foreach($line in ($_ -split '\r?\n')) {
        if ($line.IndexOf(':') -gt 0) {
            $name, $value = $line -split '\s*:\s*', 2
            $hash[$name] = $value
        }
        elseif ($line -match '\S') {
            $hash[$name] += [Environment]::NewLine + $line.Trim()
        }
    }
    $hash.GetEnumerator() | Foreach-Object {
        [PsCustomObject]@{
            'Attribute' = $_.Name
            'Value'     = $_.Value
        }
    }
}
$result | Export-Csv -Path 'D:\Test\LogResult.csv' -UseCulture -NoTypeInformation
在Excel中打开时,输出现在将显示:


对于我给出的示例,这很有效,但我没有解释什么情况是正确的。我已经更新了我的主题。@SpasDaskalov我已经编辑了我的答案并发布了代码来处理输入文件中的多个数据块谢谢。经过小小的修改,我成功地使用了你的脚本。
$hash.GetEnumerator() | Foreach-Object {
    [PsCustomObject]@{
        'Attribute' = $_.Name
        'Value' = $_.Value
    }
} | Export-Csv -Path 'D:\Test\LogResult.csv' -UseCulture -NoTypeInformation
# split the content of the file in text blocks on the double NewLine
$blocks = (Get-Content -Path 'D:\Test\TheInputLogFile.txt' -Raw) -split '(\r?\n){2,}'
# loop through each textblock, split the lines, build and convert 
# the the Hashtable and capture the results in variable $result
$result = $blocks | ForEach-Object {
    # create an ordered Hashtable to store the results
    $hash = [ordered]@{}
    foreach($line in ($_ -split '\r?\n')) {
        if ($line.IndexOf(':') -gt 0) {
            $name, $value = $line -split '\s*:\s*', 2
            $hash[$name] = $value
        }
        elseif ($line -match '\S') {
            $hash[$name] += [Environment]::NewLine + $line.Trim()
        }
    }
    $hash.GetEnumerator() | Foreach-Object {
        [PsCustomObject]@{
            'Attribute' = $_.Name
            'Value'     = $_.Value
        }
    }
}
$result | Export-Csv -Path 'D:\Test\LogResult.csv' -UseCulture -NoTypeInformation