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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.