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