Powershell 将(2)个cmdlet的结果导出到同一CSV中的不同列

Powershell 将(2)个cmdlet的结果导出到同一CSV中的不同列,powershell,powershell-3.0,powershell-4.0,Powershell,Powershell 3.0,Powershell 4.0,我是PS的新手,非常感谢您的耐心 我试图从(2)个单独的CSV文件中获取数据,然后将它们转储到一个包含(2)列的新CSV文件中。为(1)做这件事很容易,但我不知道如何做更多 这非常有效: 导入CSV C:\File1.CSV |选择“Employee”|导出CSV-路径D:\Result.CSV-NoTypeInformation 如果我添加另一个导入CSV,那么它只会覆盖现有数据: 导入CSV C:\File2.CSV |选择“部门”|导出CSV-路径D:\Result.CSV-notype信

我是PS的新手,非常感谢您的耐心

我试图从(2)个单独的CSV文件中获取数据,然后将它们转储到一个包含(2)列的新CSV文件中。为(1)做这件事很容易,但我不知道如何做更多

这非常有效:

导入CSV C:\File1.CSV |选择“Employee”|导出CSV-路径D:\Result.CSV-NoTypeInformation

如果我添加另一个导入CSV,那么它只会覆盖现有数据:

导入CSV C:\File2.CSV |选择“部门”|导出CSV-路径D:\Result.CSV-notype信息


如何使用这两个命令的信息结果填充列A和列B?谢谢你的帮助。

我会解释我将如何做到这一点,但我这样做是因为我使用对象比使用Hastable更舒适。其他人可能会使用哈希表提供答案,这可能会更好

首先,我将定义一个数组来保存您的数据,稍后可以将其导出为CSV:

$report = @()
然后,我会将您的CSV导入一个对象,该对象可以迭代:

$firstSet = Import-CSV .\File1.csv
然后,我将迭代这个过程,将每一行导入到一个具有我想要的两个属性的对象中。在您的情况下,这些是员工和部门(可能更多,您可以轻松添加)

并且,正如您在上面的示例中所看到的,将此对象添加到报表中

然后,将第二个CSV文件导入到第二个对象中进行迭代(为了更好的形式,在导入第一个CSV文件时,我会在脚本开始时这样做):

现在这里是它变得有趣的地方。仅根据您提供的信息,我假设一个文件中的所有员工与其他文件中的部门顺序相同。例如,如果我在“蛋糕品尝部”工作,我的名字在文件1的第12行,文件2的第12行写着“蛋糕品尝部”

在这种情况下,这相当容易。您只需滚动两个列表并更新报告:

$i = 0

foreach($row in $secondSet)
{
   $dept = $row.Department
   $report[i].Department = $dept

   $i++
}
在此之后,
$report
对象将在一行中包含所有员工,在另一行中包含部门。然后您可以将其导出到CSV:

$report | Export-CSV .\Result.csv -NoTypeInformation
正如我所说,如果您的数据跨两个文件对齐,那么这种方法是有效的。如果不是,那么你需要做一点花式:

foreach($row in $secondSet)
{
   $emp = $row.Employee
   $dept = $row.Department
   $report | Where {$_.Employee -eq $emp} foreach {$_.Department = $dept
}
从技术上讲,你可以这样做,但这取决于很多事情。首先,您是否在两个文件中都有该列中要匹配的数据(在我的示例中,您显然不需要这样做,否则您首先不需要这样做,但您可以在您可能有的其他字段中进行匹配,如EmployeeID或DoB)。第二,关于个人记录的主权(例如,如果您的第一个文件中有多个匹配的记录,您将遇到问题;您希望第二个文件中有重复的记录,因为每个部门都有多个人)


不管怎样,我希望这有帮助。正如我所说,可能有一种“更好”的方法可以做到这一点,但我会这样做。

我会选择这个选项:

$1 = Import-Csv -Path "C:\Users\user\Desktop\1.csv" | Select "Employee" 
$2 = Import-Csv -Path "C:\Users\user\Desktop\2.csv" | Select "Department" 
$marged = [pscustomobject]@()
$object = [pscustomobject]
for ($i=0 ; $i -lt $1.Count ; $i++){
    $object = [pscustomobject]@{
    Employees = $1[$i].Employee
    Department = $2[$i].Department}
    $marged += $object
}
$marged | ForEach-Object{ [pscustomobject]$_  } | Export-Csv -Path "C:\Users\user\Desktop\3.csv" -NoTypeInformation -Force

这比我的方法要优雅得多。虽然仍然基于两个列表长度和顺序相同的假设(根据OP,这是合理的),但你是100%正确的!工作表之间没有验证或比较。
csv
文件是否共享一个公共属性(列)?或者您只是想根据行索引(假定列表的长度相同)将它们连接起来。为了澄清这一点,您可以在问题中添加一个
csv
文件的示例吗?
foreach($row in $secondSet)
{
   $emp = $row.Employee
   $dept = $row.Department
   $report | Where {$_.Employee -eq $emp} foreach {$_.Department = $dept
}
$1 = Import-Csv -Path "C:\Users\user\Desktop\1.csv" | Select "Employee" 
$2 = Import-Csv -Path "C:\Users\user\Desktop\2.csv" | Select "Department" 
$marged = [pscustomobject]@()
$object = [pscustomobject]
for ($i=0 ; $i -lt $1.Count ; $i++){
    $object = [pscustomobject]@{
    Employees = $1[$i].Employee
    Department = $2[$i].Department}
    $marged += $object
}
$marged | ForEach-Object{ [pscustomobject]$_  } | Export-Csv -Path "C:\Users\user\Desktop\3.csv" -NoTypeInformation -Force