DoS
DoS

Reputation: 1474

How to capture data from a text file with line breaks in Powershell

i have a loads of text files i am trying to parse into powershell and can't seem to find a way to do what i am after. i basically have long text files with data group together and seperated by line breaks. all the data grouped together belongs together and essentually needs to be converted into a powershell object or an array for manipulation. i don't need any help manipulating the data, i just need a way to break the data into chunks. so for example one text file might be something like

group=name1
member=user1
member=user2
member=user3

group=name2
member=user1
member=user4
member=user5

group=name3
member=user1
member=user2

group=name4
member=user2
member=user4
member=user5
member=user6

i just need a way to pull that into powershell via get-content and anytime a line break is reached a new object or whatever needs to be created / done to store that new data. i was able to achive what i was after but only after spending quite a lot of time adding xml tags to everything which took waaaay to long. any direction or help would be greatly appriciated.

Upvotes: 0

Views: 1473

Answers (2)

mjolinor
mjolinor

Reputation: 68331

Since you're wanting objects, here's another option (requires V3 for the [ordered] and [PSCustomObject] type accelerators:

#Define a script block to create an empty hash table for object schema
$NewHT = {
 $HT = 
 [ordered]@{
   Group = ''
   Members = New-Object collections.arraylist
  }
}

#Dot source the script block to create a new hash table
.$NewHT

#Create objects from input
$NewObjects = 
Switch -Regex (Get-Content file.txt)
{
  '^Group='    { $HT.Group = $_.split('=')[1] }

  '^Member='   { [void]$HT.Members.Add($_.split('=')[1]) }

  '^\s*$'      {
                 if ($HT.Group)
                  {
                   [PSCustomobject]$HT
                   .$NewHT
                  }
               }

  Default      {Write-Warning "Unrecognized line: `n`n $_"}
}

The result using your posted data:

 $NewObjects | ft -AutoSize

Group Members              
----- -------              
name1 {user1, user2, user3}
name2 {user1, user4, user5}
name3 {user1, user2} 

That pattern should work for any file with the blank line delimited groups you describe, and produces objects without requiring any interim storage of grouped data before the object creation. Objects are created as soon as all the required data is available.

Upvotes: 2

TessellatingHeckler
TessellatingHeckler

Reputation: 29033

  • Have a hashtable for the groups.
  • Iterate over the file content.
    • When you hit a "group=" line, add to the hashtable with the group name, pointing to a new array.
    • When you hit a "member=" line, add the name to the group array.

e.g.

$groups = @{}

foreach ($line in Get-Content .\t.txt) {
    if ($line -match "group") {
        $current_group = $line.Split("=")[1]
        $groups[$current_group] = @()
    }
    if ($line -match "member") {
        $name = $line.Split("=")[1]
        $groups[$current_group] += $name
    }
}

write $groups

Sample output from your posted input:

Name                           Value                                                                                      
----                           -----                                                                                      
name1                          {user1, user2, user3}                                                                      
name2                          {user1, user4, user5}                                                                      
name3                          {user1, user2}                                                                             
name4                          {user2, user4, user5, user6}  

Then you can use $groups.keys to list all the groups, and $groups['name1'] to get them directly, etc.

Upvotes: 2

Related Questions