Reputation: 13
I have a csv file named "final results.csv", there is a header row and some data. The header data are "Alias" with underscores, for example User_Name, User_Age, User_firstN, User_LastN
I have another csv file named "header names.csv" where the actual name of the headers are stored. It has one single column, so the data looks like this.
Header
User Name
User Age
First Name
Last Name
The goal is to extract the header actual names from the 2nd file, and paste them into the first row of the first file. So the first file ("final results.csv") has a header with actual header names as opposed to aliases.
How do I achived this using Powershell? Thanks in advance!
Upvotes: 1
Views: 1085
Reputation: 8868
If I understand you right you have a CSV with header names you want to replace. Currently they are X_X
and you want to replace them with X X
. You can do it easily with Select-Object
and calculated properties. Now if you have a lot of headers that could be a lot of manual work. Here's a way to take the headers and dynamically build the calculated properties.
Demo data.
# first file
$csv = @"
User_Name,User_Age,First_Name,Last_Name
ab,20,a,b
cd,21,c,d
ef,22,e,f
"@ |ConvertFrom-Csv
# second file
$headers = @"
header
User Name
User Age
First Name
Last Name
"@ | ConvertFrom-Csv
Build the calculated properties
$SelectProps = @($headers | ForEach-Object {
@{n=$_.header;e={$($_.header.Replace('_',' '))}}
})
Here's what that should look like at this point
Name Value
---- -----
n User Name
e User_Name
n User Age
e User_Age
n First Name
e First_Name
n Last Name
e Last_Name
Now we simply replace them.
$csv | Select-Object $SelectProps
User Name User Age First Name Last Name
--------- -------- ---------- ---------
ab 20 a b
cd 21 c d
ef 22 e f
Making your code
$csv = Import-Csv "final results.csv"
$headers = Import-Csv "header names.csv"
$SelectProps = @($headers | ForEach-Object {
@{n=$_.header;e=($_.header.Replace(' ','_'))}
})
$csv | Select-Object $SelectProps |
Export-Csv -Path "final results.csv" -NoTypeInformation
But you can also just replace the first line with Get-Content
, Set-Content
, and -join
$headers = Import-Csv "header names.csv"
Set-Content -Value $(
$headers.header -join ','
Get-Content "final results.csv" | Select-Object -Skip 1
) "final results.csv"
Import-Csv "final results.csv"
User Name User Age First Name Last Name
--------- -------- ---------- ---------
ab 20 a b
cd 21 c d
ef 22 e f
Upvotes: 0
Reputation: 7087
If it were me I wouldn't bother reading in the CSV I'd simply work with it as text. All you're really doing is replacing the first line with the correct headers. Assuming the file isn't more complicated than described something like below should work:
# Get the headers:
$Headers = (Get-Content <2ndFile> | Select-Object -Skip 1) -join ','
# Combine with the CSV file skip the first row to accomplish the replace:
$Headers, @(Get-Content <1stFile> | Select-Object -Skip 1) | Set-Content <NewCsv>
Obviously, adjust file names as needed...
Upvotes: 1