Это строит вложенные списки, PowerShell ConvertTo-JSON выравнивает внешний список.
Вы можете изменить $Line in $s
на $line in (Get-Content input.txt)
.
Но я думаю, что это делает:
$s = @'
appsystem
appsystem.applications
appsystem.applications.APPactivities
appsystem.applications.APPmanager
appsystem.applications.APPmodels
appsystem.applications.MAPmanager
appsystem.applications.MAPmanager.maphub
appsystem.applications.MAPmanager.mapmanager
appsystem.applications.pagealertsmanager
appsystem.authentication
appsystem.authentication.manager
appsystem.authentication.manager.encryptionmanager
appsystem.authentication.manager.sso
appsystem.authentication.manager.tokenmanager
'@ -split "`r`n"
$TreeRoot = New-Object System.Collections.ArrayList
foreach ($Line in $s) {
$CurrentDepth = $TreeRoot
$RemainingChunks = $Line.Split('.')
while ($RemainingChunks)
{
# If there is a dictionary at this depth then use it, otherwise create one.
$Item = $CurrentDepth | Where-Object {$_.name -eq $RemainingChunks[0]}
if (-not $Item)
{
$Item = @{name=$RemainingChunks[0]}
$null = $CurrentDepth.Add($Item)
}
# If there will be child nodes, look for a 'children' node, or create one.
if ($RemainingChunks.Count -gt 1)
{
if (-not $Item.ContainsKey('children'))
{
$Item['children'] = New-Object System.Collections.ArrayList
}
$CurrentDepth = $Item['children']
}
$RemainingChunks = $RemainingChunks[1..$RemainingChunks.Count]
}
}
$TreeRoot | ConvertTo-Json -Depth 1000
Edit: Это слишком медленно? Я пробовал профилирование random pausing и нашел (не удивительно), что это внутренний вложенный цикл, который ищет массивы children
для соответствия дочерним узлам, которые попадают слишком много раз.
Это измененная версия, которая по-прежнему строит дерево, и на этот раз он также создает хеш-таблицу TreeMap ярлыков в дереве, ко всем ранее созданным узлам, поэтому они могут сразу перепрыгивать их, а не искать списки children
для них.
Я сделал тестовый файл, некоторые 20k случайных строк. Исходный код обработал его за 108 секунд, это делается через 1,5 секунды, и результат соответствует.
$TreeRoot = New-Object System.Collections.ArrayList
$TreeMap = @{}
foreach ($line in (Get-Content d:\out.txt)) {
$_ = ".$line" # easier if the lines start with a dot
if ($TreeMap.ContainsKey($_)) # Skip duplicate lines
{
continue
}
# build a subtree from the right. a.b.c.d.e -> e then d->e then c->d->e
# keep going until base 'a.b' reduces to something already in the tree, connect new bit to that.
$LineSubTree = $null
$TreeConnectionPoint = $null
do {
$lastDotPos = $_.LastIndexOf('.')
$leaf = $_.Substring($lastDotPos + 1)
$_ = $_.Substring(0, $lastDotPos)
# push the leaf on top of the growing subtree
$LineSubTree = if ($LineSubTree) {
@{"name"=$leaf; "children"=([System.Collections.ArrayList]@($LineSubTree))}
} else {
@{"name"=$leaf}
}
$TreeMap["$_.$leaf"] = $LineSubTree
} while (!($TreeConnectionPoint = $TreeMap[$_]) -and $_)
# Now we have a branch built to connect in to the existing tree
# but is there somewhere to put it?
if ($TreeConnectionPoint)
{
if ($TreeConnectionPoint.ContainsKey('children'))
{
$null = $TreeConnectionPoint['children'].Add($LineSubTree)
} else {
$TreeConnectionPoint['children'] = [System.Collections.ArrayList]@($LineSubTree)
}
} else
{ # nowhere to put it, this is a new root level connection
$null = $TreeRoot.Add($LineSubTree)
}
}
$TreeRoot | ConvertTo-Json -Depth 100
(@ код mklement0 занимает 103 секунд, и производит дико другой вывод - 5.4m символы JSON вместо 10.1M символов JSON [Edit: потому что мой код позволяет использовать несколько корневых узлов в списке, который мой тест. файл имеет, и их код не позволяет, что])
Auto сгенерированные PS помогают ссылки из моего кодоблок (если таковые имеются):
Я ответил, но я до сих пор downvoting, потому что вы имеете просто ушел «вот проблема, мне это нужно». – TessellatingHeckler
@ TessellatingHeckler, Да, я знаю. Я не смог найти примеры чего-либо подобного: большинство примеров объектов JSON читают элемент JSON в PS. Был у меня на уме. – wergeld
Я видел очень похожий вопрос здесь, я пытался ответить, но не мог работать в то время - другие люди ответили, что может быть полезной ссылкой, но я не могу найти его сейчас, слишком много результаты для «powershell» и «json». – TessellatingHeckler