更新:根据其他项目需求使用标记的首选解决方案。由于其他一些项目需求,我还对其进行了稍微修改,以丢弃源代码中未提供的任何列。
$refTable = @'
SourceColumn,TargetColumn
LastName,Last_Name
DOB,Date_Of_Birth
FirstName,First_Name
'@ | ConvertFrom-Csv
$source = @'
FirstName,DOB,NotInRefCol,LastName
Tom,06/07/1940,1,Jones
Bill,11/27/1955,2,Nye
William,04/01/1564,3,Shakespeare
'@ | ConvertFrom-Csv
$map = @{}
foreach($line in $refTable) {
$map[$line.SourceColumn] = $line.TargetColumn
}
foreach($line in $source) {
$out = [ordered]@{}
foreach($prop in $line.PSObject.Properties) {
if (!($refTable.SourceColumn.Contains($prop.Name))) {
continue
}
if($newCol = $map[$prop.Name]) {
$out[$newCol] = $prop.Value
continue
}
$out[$prop.Name] = $prop.Value
}
[pscustomobject]$out
}
我有一组 CSV 格式的数据,我尝试根据映射文档中的列名称输出具有不同标题的相同数据。为了清楚起见,下面的列名称只是一个示例,但名称可能会有很大不同,并且顺序可能与映射文件中列的顺序不匹配。我最近没有做太多 Powershell 工作,所以我很难开始。我似乎无法弄清楚根据我正在查看的数据查找列名称的逻辑。例如,如果我执行 foreach ($row in $source)
我怎么知道如何对列进行排序?任何帮助将不胜感激!
示例:
map.csv
SourceColumn,TargetColumn
LastName,Last_Name
DOB,Date_Of_Birth
FirstName,First_Name
source.csv
FirstName,LastName,DOB
Tom,Jones,06/07/1940
Bill,Nye,11/27/1955
William,Shakespeare,04/01/1564
期望的输出:
输出.csv
Last_Name,Date_Of_Birth,First_Name
Jones,06/07/1940,Tom
Nye,11/27/1955,Bill
Shakespeare,04/01/1564,William
最佳答案
注意:以下内容保留 source.csv
中的列顺序,并简单地替换新的列名称。这样可以对数据 CSV 进行相对快速的纯文本处理。
# Initialize an ordered hashtable.
$map = [ordered] @{}
# Fill it with the mapping of source to target column names.
Import-Csv map.csv | ForEach-Object { $map[$_.SourceColumn] = $_.TargetColumn }
# Read the data CSV into header line and all data lines.
# Note: You can speed this up with a somewhat obscure optimization:
# $sourceHeader, $sourceData = (Get-Content -ReadCount 0 source.csv)
$sourceHeader, $sourceData = Get-Content source.csv
# Construct the new header line via the previously constructed
# map (ordered hashtable).
$newSourceHeader = ($sourceHeader -split ',' | ForEach-Object { $map[$_] }) -join ','
# Save the new header followed by the data lines to a (new) output
# file. Adjust the target file and -Encoding as needed.
Set-Content -Encoding utf8 output.csv -Value $newSourceHeader, $sourceData
如果您确实需要 map.csv
中的特定列排序,一个低效但简单的解决方案是将以下内容应用于由以下代码生成的 output.csv
文件:上面的代码:
Import-Csv output.csv |
Select-Object (Import-Csv map.csv).TargetColumn |
Export-Csv output_new.csv -Encoding utf8 -NoTypeInformation
关于powershell - 根据映射文件将列映射到新列名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71357411/