将列表样式文本文件读入Powershell数组

时间:2019-07-08 12:53:42

标签: list powershell file text

我提供了一个文本文件中的字符串块列表,我需要将其放在Powershell的数组中。

列表看起来像这样

a:1
b:2
c:3
d:
e:5
[blank line]
a:10
b:20
c:30
d:
e:50
[blank line]
... 

,我希望它在Powershell数组中可以进一步使用它。

我正在使用

$output = @()

Get-Content ".\Input.txt" | ForEach-Object {

    $splitline = ($_).Split(":")

    if($splitline.Count -eq 2) {

        if($splitline[0] -eq "a") {
            #Write-Output "New Block starting"
            $output += ($string)
            $string = "$($splitline[1])"

        } else {

            $string += ",$($splitline[1])"
        }
    }    
}

Write-Host $output -ForegroundColor Green

$output | Export-Csv ".\Output.csv" -NoTypeInformation
$output | Out-File ".\Output.txt"

但是这整个过程感觉很麻烦,并且输出不是一个csv文件,这是我认为这是因为我使用数组的方式。 Out-File确实会生成一个包含用逗号分隔的行的文件。

也许有人可以向我推向正确的方向。

Thx x

2 个答案:

答案 0 :(得分:2)

一种解决方案是将您的数据转换为哈希表数组,这些哈希表可以读取到自定义对象中。然后可以根据需要导出,格式化或读取输出数组对象。

$hashtables = (Get-Content Input.txt) -replace '(.*?):','$1=' | ConvertFrom-StringData
$ObjectShell = "" | Select-Object ($hashtable.keys | Select-Object -Unique)

$output = foreach ($hashtable in $hashtable) {
  $obj = $ObjectShell.psobject.Copy()
  foreach ($n in $hashtable.GetEnumerator()) {
    $obj.($n.key) = $n.value
  }
  $obj
}
$output
$output | Export-Csv Output.csv -NoTypeInformation

说明:

每行的第一个冒号(:)替换为=。这使ConvertFrom-StringData可以创建一个哈希表数组,其中=的LHS上的值是键,而=的RHS上的值是值。如果您知道每行只有一个:,则可以简化-replace的操作。

$ObjectShell只是一个具有您数据呈现的所有属性的对象。无论是否为它们分配值,都需要为每一行数据显示所有属性。否则,您在控制台中的CSV输出或表格视图将出现问题。

第一个foreach遍历$hashtables数组。然后,我们需要枚举每个哈希表以找到键和值,这由第二个foreach循环执行。每个键/值对都存储为$ObjectShell的副本。 .psobject.Copy()方法用于防止引用原始对象。更新作为参考的数据将更新原始对象的数据。

$output包含所有已处理数据的对象数组。

输出的可用性:

# Console Output

$output | format-table

a  b  c  d e
-  -  -  - -
1
   2
      3

           5

10
   20
      30

           50

# Convert to CSV

$output | ConvertTo-Csv -NoTypeInformation
"a","b","c","d","e"
"1",,,,
,"2",,,
,,"3",,
,,,"",
,,,,"5"
,,,,
"10",,,,
,"20",,,
,,"30",,
,,,"",
,,,,"50"

# Accessing Properties

$output.b
2
20

$output[0],$output[1]

a : 1
b :
c :
d :
e :

a :
b : 2
c :
d :
e :

替代转化:

$output = ((Get-Content Input.txt -raw) -split "(?m)^\r?\n") | Foreach-Object { 
  $data = $_ -replace "(.*?):(.*?)(\r?\n)",'"$1":"$2",$3'
  $data = $data.Remove($data.LastIndexOf(','),1)
  ("{1}`r`n{0}`r`n{2}" -f $data,'{','}') | ConvertFrom-Json
}
$output | ConvertTo-Csv -NoType

替代说明:

由于ConvertFrom-StringData不保证哈希表的键顺序,因此该替代方法为文件准备了JSON转换。如果每个组的顺序相同,这将保持文件中列出的属性顺序。否则,将遵守第一组的财产顺序。

所有属性及其各自的值都用每行的第一个:字符分隔。属性和值均用双引号引起来。每个属性行都由,分隔。然后最后添加开始{和结束}。所得的JSON格式的字符串将转换为自定义对象。

答案 1 :(得分:1)

您可以按\n换行符分隔,请参见示例:

$text = @"
a:1
b:2
c:3
d:
e:5

a:10
b:20
c:30
d:
e:50
e:50
e:50

e:50
"@

$Array = $text -split '\n' | ? {$_}
$Array.Count
15

如果要排除空行,​​请添加? {$_}

以您的示例为例:

$Array = (Get-Content ".\Input.txt") -split '\n' | ? {$_}