powershell - 将 CSV 与包含另一个 CSV 的两列的数组进行比较
问题描述
我有两个 CSV。CSV1 由 3 列组成:名称、用户名、主组;CSV2 由 4 列组成:名称、用户名、部门、部门。两个 CSV 都按名称列排序。
我需要将来自这两个 CVS 的数据,特别是来自 CVS2 的Department和Division与来自 CSV1 的MainGroup进行比较。然后将结果导出到 CVS 文件中,其中将包含Name、Username、MatchedGroup。因此,在结果 CVS 的第三列中,我想保留Department和Division与MainGroup列的比较结果。即,如果来自 CVS2 的Department或Division列的值与来自 CSV1 的 MainGroup 列的值匹配,则将匹配的值保留在结果中。
是的,我可以使用Compare-Object
cmdlet,但很难想象我需要比较值并获得结果的循环。此外,MainGroup列可以有几个值除以逗号,这就是为什么我必须比较列并保留与MainGroup列匹配或保留结果原始值的列,如果Department和Division为空。
CSV1 示例:
姓名 | 用户名 | 主组 |
---|---|---|
戴夫戴维森 | 戴夫 | NCR |
雨果·洛森 | 雨果 | 军团 |
海乌戈 | 海 | CBA |
伦达尔回声 | 伦达尔 | NCR,CBA |
CVS2 示例:
姓名 | 用户名 | 部门 | 分配 |
---|---|---|---|
戴夫戴维森 | 戴夫 | NCR | |
雨果·洛森 | 雨果 | 军团 | NCR |
海乌戈 | 海 | ||
伦达尔回声 | 伦达尔 | 军团 |
解决方案
毫无疑问,有一种更简洁、更好的方法可以用更少的代码执行此操作 - 但是我通常发现创建一个类来填充 CSV 比较的结果更容易,因为这样可以更轻松地获得 CSV 的输出。
这可以简化,但希望这将有助于解释循环/流程。将其复制到文件中(例如;Comapre-Csv.ps1
),然后像这样运行它;
.\Compare-Csv.ps1 -SourceCsv .\csv_1.csv -ComparisonCsv .\csv_2.csv -ExportPath .\result.csv
脚本:
param (
[string]
$SourceCsv,
[string]
$ComparisonCsv,
[string]
$ExportPath
)
# Import both CSV's
$source = Import-Csv $SourceCsv
$comparison = Import-Csv $ComparisonCsv
# Create a class/array for easier CSV export
class ResultLine {
[string]$Name
[string]$UserName
[string]$MainGroup
}
[ResultLine[]]$results = @()
foreach($sourceRow in $source) {
# Find row in the comparison CSV by filtering to UserName
$comparisonRow = $comparison | Where-Object -Property UserName -eq $sourceRow.UserName
if($comparisonRow) {
Write-Host "Comparing [$($sourceRow.UserName)] to [$($comparisonRow.UserName)]"
# default to MainGroup - will be be overwritten if found in comparison
[string]$mainGroup = $sourceRow.MainGroup
# Check the department/division values from the comaprison row
if(($comparisonRow.Department) -and ($comparisonRow.Division)) {
# If the department & division are the same, just use the department
if($comparisonRow.Department -eq $comparisonRow.Division) {
$mainGroup = $comparisonRow.Department
} else {
$mainGroup = "$($comparisonRow.Department),$($comparisonRow.Division)"
}
}
elseif($comparisonRow.Department) {
$mainGroup = $comparisonRow.Department
}
elseif($comparisonRow.Division) {
$mainGroup = $comparisonRow.Division
}
# Store the result
$results += [ResultLine]@{
Name = $sourceRow.Name
UserName = $sourceRow.UserName
MainGroup = $mainGroup
}
}
else {
Write-Host "[$($sourceRow.UserName)] not found in [$ComparisonCsv]" -ForegroundColor Yellow
}
}
# Export CSV
$results | Export-Csv -Path $ExportPath -NoTypeInformation
就像我说的,有更短、更清洁的方法——但希望这会有所帮助。请记住,如果UserName
不在源中,但在目标中,则此脚本将无法处理。
推荐阅读
- python - 缺少 1 个必需的位置参数:'y'
- reactjs - 使用 Java 和 React 捕获 SQLExceptions
- excel - 怎么知道跑步机够不够用?
- sql-server - Oracle 和 SQL Server(长文本)
- git - Git从一个单独的git repo的子目录添加构建目录
- php - Docker 镜像构建不同版本的应用程序
- php - 跟踪访客设置 VPN 或代理 ni php
- python - 如何在python中获取列表的子集而不重复?
- typescript - 在 Mac 上构建后在电子应用程序中找不到模块
- kivy - 如何将功能分配给 kivyMD 按钮