Parsing a string in which data could be anything

This topic contains 15 replies, has 2 voices, and was last updated by Profile photo of bvi1998 . bvi1998 . 6 months, 3 weeks ago.

  • Author
    Posts
  • #38839
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    Hi, I am running a curl command which would result in something like this:

    {"data": ["OS Disk", "CPU Usage", "Memory Usage", "All Disks"]}

    However, the values inside of the quotation marks could be different at any time.

    I am trying to end up with variables for each of the above, for example... the next step would be for me to then query each of those. For instance, after I retrieve "CPU Usage" I will then be running another command to find out the details of the "CPU Usage" ... can someone help? I know this is a regex thing but way above my knowledge!
    Thanks!

  • #38841
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Looks like JSON to me. Simplest way is probably just to use ConvertFrom-Json:

    $curlOutput = '{"data": ["OS Disk", "CPU Usage", "Memory Usage", "All Disks"]}'
    $object = $curlOutput | ConvertFrom-Json
    
    foreach ($item in $object.data)
    {
        # Do something with $item
    }
    
  • #38842
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    I found this which works for the first value in the string:

    if ($string -match '"(.+?)"') {
    $Matches[1]
    }

    In this case, $Matches[1] has the value "data".
    Now I need to keep going in the string to capture all of the values between quotes...
    Can someone help, thanks!

  • #38843
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    Ok thanks Dave, let me give that a shot!

  • #38844
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    works like a charm, and so simple, thanks!

  • #38894
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    I need to remove one item in $object.data.deleteme ....
    Once I have the array, how can I remove one of the members?
    In other words, I want to remove the source: nrpe item:

    source : nrpe
    tag : {Windows_Physical, Microsoft_Windows_Server_2008_R2_Standard_, winvm}

    Thanks!

  • #38897
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Depends on where you want that removed. Just in your object in memory for some reason, or on the server itself? If it's the latter, then it depends on how your web interface works.

  • #38899
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    Basically I am going to send information back to the host API using the json file.
    However, though the information I received when executing the XGET, there are two extra fields which the API will not accept. The json data looks like this:
    {
    "source": "I don't want this",
    "tag": [
    "Windows_Physical",
    "Microsoft_Windows_Server_2008_R2_Standard",
    ],
    "parents": [

    ],
    "address": [
    "10..0.0.0"
    ],
    "url": " ",
    "notes": " ",
    "hostname": "I don't want this",
    "umiworker": "the moon",
    "hosttype": "server"
    }

    So basically I need to exclude the source and hostname names and data. I will take the data minus the those two fields/data and send a curl statement back. Basically I am doing this entire exercise because the only way to change server information in this API is to do the XGET, delete the server, modify the IP address for instance, then PUT the information back using a curl statement again 🙂

    Thanks!

  • #38902
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Gotcha. Probably something along these lines, then:

    $newJsonData = $oldJsonData |
                   ConvertFrom-Json |
                   Select-Object -ExcludeProperty source,hostname |
                   ConvertTo-Json
    
  • #39016
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    Thanks Dave.
    I had to modify your code just a bit:
    $newJsonData.data = $oldJsonData.data |
    ConvertFrom-Json |
    Select-Object -ExcludeProperty source,hostname |
    ConvertTo-Json

    For the last piece of the puzzle!
    The data from the curl command looked like so:

    '{"data": ["OS Disk", "CPU Usage", "Memory Usage", "All Disks"]}'

    I am able to remove a couple of fields

    Now I need the format to be like to have the proper escape characters so that I can send it back to the API 🙂

    in other words the data above should end up looking like this for the curl command:

    "{\"data\": [\"OS Disk\", \"CPU Usage\", \"Memory Usage\", \"All Disks\"]}"

    Can help me with that last piece?
    I have tried a few things and cannot get there from here!
    Thanks

  • #39018
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Looks like you're only escaping single quotes, so this might be enough:

    $curlParameter = $newJsonData.data -replace '"', '\"'
    
  • #39019
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    (note: don't worry about the set of double quotes around the whole string. When you call an executable like curl.exe, PowerShell will quote the arguments for you anyway.)

  • #39044
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    Hi Dave,
    To recap:

    normally I do:

    $ServerData = '{"data": {"source": "nrpe", "tag": ["OS"], "parents": [], "address": ["10.0.0.0"],"hostname": "server","hosttype": "server"}}' | convertto-json

    And the result in $serverData is perfect to use for curl:

    "{\"data\": {\"source\": \"nrpe\", \"tag\": [\"OS\"], \"parents\": [], \"address\": [\"10.0.0.0\"],\"hostname\": \"server\",\"hosttype\": \"server\"}}"

    In the new process I remove data by doing the following:

    $ServerData = '{"data": {"source": "nrpe", "tag": ["OS"], "parents": [], "address": ["10.0.0.0"],"hostname": "server","hosttype": "server"}}' | convertto-json

    $ServerJson = $ServerData | ConvertFrom-Json

    $ServerJson.data = $ServerJson.data | Select-Object * -ExcludeProperty source, hostname | ConvertTo-Json

    Now $serverJson.data is in this format:

    {
    "tag": [
    "OS"
    ],
    "parents": [

    ],
    "address": [
    "10.0.0.0"
    ],
    "hosttype": "server"
    }

    The last step in this I need to do is convert this back to:

    "{\"data\": {\"tag\": [\"OS\"], \"parents\": [], \"address\": [\"10.0.0.0\"],\"hosttype\": \"server\"}}"

    I have been through the trials and tribulations of trying to replace charaters and such in the past which has not always worked, so I would really like to do this with a conversion of some sort.
    I am just not clear on how I can get the $serverjson.data back to the desired format with the escape characters.

    Do you have any ideas?
    Thanks!

  • #39045
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Ah, gotcha. Use the -Compress switch when you call ConvertTo-Json and you should be fine. 🙂

  • #39051
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    That was it, thanks! All of the suffering we Win admins have to endure when forcing our data into a Linux API, among other Linux tools we have to use...

    In case others need help, here is the entire process.

    Data coming from a curl call:

    {"data": {"source": "nrpe", "tag": ["OS"], "parents": [], "address": ["10.0.0.0"],"hostname": "server","hosttype": "server"}}'

    Set a variable to manipulate the data:

    $ServerData = '{"data": {"source": "nrpe", "tag": ["OS"], "parents": [], "address": ["10.0.0.0"],"hostname": "server","hosttype": "server"}}' | convertto-json

    Ready to remove some data:

    $ServerJson = $ServerData | ConvertFrom-Json

    $ServerJson = $ServerJson.data | Select-Object * -ExcludeProperty source, hostname | ConvertTo-Json -compress

    Now the data is compressed but I need the escape characters for curl:

    $ServerJsonResult | convertto-json

    Then for my situation I have to change the double quotes to single quotes.
    $result = $result -replace '"{', "'{"
    $result = $result -replace '}"', "}'"

    Probably an easier way to do that but it works... 🙂
    voila, PUT the data back!

    Thanks so much for your time Dave!

  • #39069
    Profile photo of bvi1998 .
    bvi1998 .
    Participant

    To finish the job 🙂 ...

    I have another situation in which I need to get those array values and store them in variables.

    $ServerJson.data has data that I also will need to separate out

    So for each value in $serverjson.data, I need to set a variable called $tag for the first value, $tag1 for the second value, and so on.

    I have tried a number of things, none of which work.

    Can you lead me a bit?

    I see that if I run:

    $ServerJson.data | foreach-object {$_}
    {
    write-host $_

    }
    I can see each object.

    Thanks!

You must be logged in to reply to this topic.