0

I have a generic text, not PSCustom, not CSV, not JSON but has some structure

Field1:ABC
Field2: DEF

Field1:HKA
Field3:YZ

Field1:123
Field2:234
Field4:876
Field5:XUZ

Obviously, the text is a multiple records with fields and missing fields, each record is separated with CR-LF.

Is there an efficient way to parse the string and extract only Field1 and Field2 out of the records and put the results in JSON?

I tried put the string into a string variable called $s then

$s | select -ExpandProperty Field1,Field2

But I got this error

Select-Object : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'ExpandProperty'. Specified method is not supported.

If I tried

$s | select -ExpandProperty Field1

Then I got the error saying Field1 not being a property.

I guess I kinda understand the error but not sure how to fix it. I think I have to somehow convert the text into a structured table first then extract it. But how do I do that?

3
  • You're trying to expand a 'property' on a string. This won't work. You have to create a PSCustom Object and place the values into that object, then you can use it in the pipe and expand properties that way. The solution I could think of is split the string on a new line into an array and use a foreach loop on that to create your custom object. Commented Sep 15, 2017 at 14:11
  • I also notice you have multiable field1's and 2's and so forth....Is this sample you gave correct? Commented Sep 15, 2017 at 14:48
  • @ArcSet: Yes, it is. The "plain text" is not actually plain text but structured one. They are records with field1, field2,...,fieldn. Some fields show up because they have values, some don't since they are blank. But I am only interested in specific fields, let's say field1 and field2. If they are blank, then I would leave space in the value. Commented Sep 15, 2017 at 14:51

1 Answer 1

3

Select-Object won't work on a string. You need to process the string into a list of objects first. Also, you cannot expand more than one property at a time.

Split the text at 2+ consecutive line breaks:

(Get-Content 'C:\temp\input.txt' | Out-String) -split '(\r?\n){2,}'

Split each fragment into lines, split each line at the separator, and fill a hashtable with the key/value pairs:

$ht = @{}
$fragment -split '\r?\n' | ForEach-Object {
    $key, $value = $_ -split '\s*:\s*'
    $ht[$key] = $value
}

Then build objects from the hashtables:

New-Object -Type PSObject -Property $ht

With that you can select the properties Field1 and Field2 like this:

... | Select-Object Field1, Field2
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! That is very slick... However, for some reason, after running the script, the fields from all records are combined into only 1 record... so $ht is only one record with Field1 to Field5 while I was looking for is $ht[0]={Field1:..,Field2}, $ht[1]={Field1...,Field3],$ht[3]={...}.... I probably need to twist your code a bit to get what I want, but at least I got the gist of what should be done!
Most likely you didn't create a new hashtable for each fragment
ah... that's probably it! I am new and still learning my ropes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.