Чтение текстового файла стиля списка в массив powershell - PullRequest
2 голосов
/ 08 июля 2019

Мне предоставлен список строковых блоков в текстовом файле, и мне нужно, чтобы это было в массиве 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 х

Ответы [ 2 ]

2 голосов
/ 08 июля 2019

Одним из решений является преобразование ваших данных в массив хеш-таблиц, которые можно прочитать в пользовательский объект.Затем объект выходного массива можно экспортировать, отформатировать или прочитать, как требуется.

$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 голос
/ 08 июля 2019

Вы можете разделить на \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' | ? {$_}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...