Reputation: 281
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
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
Reputation: 2952
You can actually index your array with ($MyRow[1]).age
in order to get the age of the first row.
Upvotes: 0
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