I've spent all day trying to figure this out, any help would be great!
This is the text I want to parse into Json
:
============ Get Mouse Position ===============
Get Mouse Position
GetMousePos
Get the mouse position first
Command one
Command two
Command three
============ Set Mouse Position ===============
Set Mouse Position
SetMousePos
Set the mouse position after
Command one
Command two
Command three
The Json
output I am aiming for is:
{
"Get Mouse Position": {
"Trigger": "GetMousePos",
"Description": "Get the mouse position first",
"body": [
"Command one",
"Command two",
"Command three"
]
},
"Set Mouse Position": {
"Trigger": "SetMousePos",
"Description": "Set the mouse position after",
"body": [
"Command one",
"Command two",
"Command three"
]
},
}
I've been doing allot of reading and experimenting but I just cant seem to figure it out. the ConvertFrom-StringData command gets me mostly there but it does not seem to support arrays for a single key (for command one, two, three section).
I tried to experimenting with PSCustomObject
and ConvertTo-Json
like below and it gives me perfect Json
output but I cant wrap my head around how to properly code my data into the example below for every potential ===== [Object] ====
section there could be.
$myObject = [PSCustomObject]@{
'Get Mouse Position' = [ordered]@{
Trigger = 'GetMousePos'
Description = 'Get the mouse position first'
body = @(
'Command one'
'Command two'
'Command three'
)
}
'Set Mouse Position' = [ordered]@{
Trigger = 'Set MousePos'
Description = 'Set the mouse position last'
body = @(
'Command one'
'Command two'
'Command three'
)
}
}
I would really like to know some potential ways I can approach this, that would be so wonderful. Also, a related question. Does the ConvertFrom-StringData command not support multiple values/arrays for a single key? Thanks allot
PS: I have taken the liberty to also ask this question in other communities.
CodePudding user response:
Ok, since I already did the work I'll go off the assumption that the records are split by the ======
lines, and that within a record the first line denotes the title, the second the trigger, the third the description, and the rest is the body. My suggestion is to read the whole file in as a multi-line string, split on the === lines, and pass to a ForEach-Object
loop. For the beginning of the loop define an empty object, and for each record passed split it on line breaks into 4 things, and setup your hashtable from that split, and add a property to the object based off that info as well. At the end of the loop output your object that now has a bunch of properties, and pass it to convertto-json
.
(Get-Content MyFile.txt -Raw) -split '(?ms)=. ?[\r\n] '|
ForEach-Object -begin {
$MyObj=New-Object PSObject
} -process {
$Split=$_ -split '[\r\n] ',4;
$ThisVal = [ordered]@{
Trigger=$Split[1].trim();
Description=$Split[2].trim();
Body=$Split[3] -split '[\r\n] ' -replace '^\s*|\s*$'
};
Add-Member -InputObject $MyObj -NotePropertyName $Split[0].Trim() -NotePropertyValue $ThisVal
} -end {
$MyObj
}|convertto-json
CodePudding user response:
# Initialize an ordered hashtable.
$oht = [ordered] @{}
# Split the input file into blocks of lines, not including the header
# (separator) lines.
(Get-Content -Raw file.txt) -split '(?m)^===.*\r?\n' -ne '' | ForEach-Object {
# Parse the block of lines into individual lines
$name, $trigger, $description, $body = $_ -replace '\r?\n\z' -split '\r?\n'
# Add an entry to the ordered hashtable.
$oht[$name.Trim()] = [ordered] @{
Trigger = $trigger.Trim()
Description = $description.Trim()
body = $body.Trim()
}
}
# Convert the resulting ordered hashtable to JSON
$oht | ConvertTo-Json
Note: The above uses a nested [ordered]
hashtable instead of a nested [pscustomobject]
, as that is sufficient for to-JSON conversion and makes iterative construction easier (while also being more light-weight).
If a nested [pscustomobject]
instance is desired, replace [ordered]
inside the ForEach-Object
script block with [pscustomobject]
for the nested instance, and then use [pscustomobject] $oht
to construct the outer instance.
See also: