如何将大的垂直文本文件转置并解析为带有标题的CSV文件?

时间:2019-03-18 13:00:13

标签: powershell csv scripting

我有一个大型文本文件(* .txt),格式如下:

; KEY 123456
; Any Company LLC
; 123 Main St, Anytown, USA

SEC1 = xxxxxxxxxxxxxxxxxxxxx
SEC2 = xxxxxxxxxxxxxxxxxxxxx
SEC3 = xxxxxxxxxxxxxxxxxxxxx
SEC4 = xxxxxxxxxxxxxxxxxxxxx
SEC5 = xxxxxxxxxxxxxxxxxxxxx
SEC6 = xxxxxxxxxxxxxxxxxxxxx

重复此操作约350-400个键。这些是HASP密钥以及与它们关联的SEC代码。我正在尝试将此文件解析为CSV文件,并以KEY和SEC1-SEC6作为标题,并填充行。这是我尝试获取的格式:

KEY,SEC1,SEC2,SEC3,SEC4,SEC5,SEC6
123456,xxxxxxxxxx,xxxxxxxxxxx,xxxxxxxxxx,xxxxxxxxxx,xxxxxxxxxx,xxxxxxxxxx
456789,xxxxxxxxxx,xxxxxxxxxx,xxxxxxxxxx,xxxxxxxxxx,xxxxxxxxxx,xxxxxxxxxx

我已经能够使脚本在文本文件(我的测试文件)中仅使用一个键导出到CSV,但是当我尝试在完整列表上运行该脚本时,它仅导出最后一个键和秒代码。

$keysheet = '.\AllKeys.txt'
$holdarr = @{}

Get-Content $keysheet | ForEach-Object {
if ($_ -match "KEY") {
    $key, $value = $_.TrimStart("; ") -split " "
    $holdarr[$key] = $value }
elseif ($_ -match "SEC") {
    $key, $value = $_ -split " = "
    $holdarr[$key] = $value }
}

$hash = New-Object PSObject -Property $holdarr
$hash | Export-Csv -Path '.\allsec.csv' -NoTypeInformation

当我在完整列表上运行它时,它还会添加几个看起来像属性而不是值的额外列。

任何帮助使它生效的帮助。

谢谢。

3 个答案:

答案 0 :(得分:3)

这是我建议的方法:

<p>

答案 1 :(得分:1)

这是一种方法。

& {
    $entry = $null
    switch -Regex -File '.\AllKeys.txt' {
        "KEY" {
            if ($entry ) {
                [PSCustomObject]$entry
            }
            $entry = @{}
            $key, $value = $_.TrimStart("; ") -split " "
            $entry[$key] = [int]$value
        }
         "SEC" {
            $key, $value = $_ -split " = "
            $entry[$key] = $value 
        }
    }
    [PSCustomObject]$entry
} | sort KEY | select KEY,SEC1,SEC2,SEC3,SEC4,SEC5,SEC6 |
Export-Csv -Path '.\allsec.csv' -NoTypeInformation

答案 2 :(得分:1)

让我们利用ConvertFrom-StringData的力量

  

将包含一个或多个键和值对的字符串转换为哈希表。

所以我们要做的是

  1. 拆分为文本块
  2. 编辑“;键”行
  3. 删除空白行或分号行。
  4. 传递给ConvertFrom-StringData以创建哈希表
  5. 将其转换为PowerShell对象

$path = "c:\temp\keys.txt"
# Split the file into its key/sec collections. Drop any black entries created in the split
(Get-Content -Raw $path) -split ";\s+KEY\s+" | Where-Object{-not [string]::IsNullOrWhiteSpace($_)} | ForEach-Object{
    # Split the block into lines again
    $lines = $_ -split "`r`n" | Where-Object{$_ -notmatch "^;" -and -not [string]::IsNullOrWhiteSpace($_)}
    # Edit the first line so we have a full block of key=value pairs.
    $lines[0] = "key=$($lines[0])"
    # Use ConvertFrom-StringData to do the leg work after we join the lines back as a single string.
    [pscustomobject](($lines -join "`r`n") | ConvertFrom-StringData)

} | 
    # Cannot guarentee column order so we force it with this select statement.
    Select-Object KEY,SEC1,SEC2,SEC3,SEC4,SEC5,SEC6

立即使用Export-CSV让您心满意足。