Keith
Keith

Reputation: 281

Index into powershell Import-Csv row like an array

I am importing data from various csv files, usually with 4 or 5 fields.

e.g. one might look like:

id, name, surname, age

1,tom,smith,32

2,fred,bloggs,50

I have managed to grab the header row titles into and array that looks like:

id, name, surname, age

the first data row looks like:

@{ID=1; name=tom; surname=smith; age=32}

say I assign it to $myRow what I want to be able to do is access the ID, name etc field in $myRow by index, 0, 1, 2 etc, not by the property name.

Is this possible?

Thanks

Upvotes: 2

Views: 7326

Answers (3)

Walter Mitty
Walter Mitty

Reputation: 18940

When I wanted to do something similar, I went about it differently. I used Import-Csv to get the contents into a table. Then I stepped through the table, row by row, and used an inner loop to retrieve the field values, one by one into variables with the same name as the column name.

This created a context where I could apply the values to variables embedded in some kind of template. Here is an edited version of the code.

foreach ($item in $list) {
   $item | Get-Member -membertype properties | foreach {
      Set-variable -name $_.name -value $item.$($_.name)
      }
   Invoke-expression($template)  >> Outputfile.txt
   }

I'm writing the expanded templates to an output file, but you get the idea. This end up working more or less the way mail merge applies a mailing list to a form letter.

I wouldn't use this approach for more than a few hundred rows and a dozen columns. It gets slow.

Explanation:

The inner loop needs more explanation. $list is a table that contains the imported image of a csv file. $item is one row from this table. Get-Member gets each field (called a property) from that row. Each field has a name and a value. $_.name delivers the name of the current field. $item.($_.name) delivers the value. Set-Variable creates a variable. It's very inefficient to create the same variables over and over again for each row in the table, but I don't care.

This snippet was clipped from a larger snippet that imports a list and a template, produces an expansion of the template for each item in the list, and outputs the series of expansions into a text file. I didn't include the whole snippet because it's too far afield from the question that was asked.

Upvotes: 1

Alex_P
Alex_P

Reputation: 2952

You can actually index your array with ($MyRow[1]).age in order to get the age of the first row.

Upvotes: 0

mjolinor
mjolinor

Reputation: 68273

You can do something like this, but it may be slow for large sets of rows and/or properties:

$users = 
import-csv myusers.csv |
foreach {
 $i=0
 foreach ($property in $_.psobject.properties.name)
   {
    $_ | Add-Member -MemberType AliasProperty -Name $i -Value $property -passthru
    $i++
   }
 }

That just adds an Alias property for each property name in the object

Upvotes: 2

Related Questions