【问题标题】:Add Column to CSV file Using Other CSV file使用其他 CSV 文件将列添加到 CSV 文件
【发布时间】:2018-11-29 22:27:51
【问题描述】:

我正在处理两个 CSV 文件。一个保存用户的姓名,另一个保存他们相应的电子邮件地址。我想要做的是将它们结合起来,使用户是第 1 列,电子邮件是第 2 列,并将其输出到一个文件。到目前为止,我已经设法将电子邮件 csv 文件中的第二列添加到用户 csv 文件中,但使用空白行数据。以下是我正在使用的代码:

$emailCol= import-csv "C:\files\temp\emailOnly.csv" | Select-Object -skip 1
$emailArr=@{}
$i=0

$nameCol = import-csv "C:\files\temp\nameOnly.csv"

foreach ($item in $emailCol){
                             $nameCol | Select *, @{
                                                    Name="email";Expression= 
                                                    {$emailArr[$i]}
                                                    } | Export-Csv -path 
                             C:\files\temp\revised.csv -NoTypeInformation
                             } 

更新:以下对我有用。谢谢 BenH!

function combineData    {
                        #This function will combine the user CSV file and 
                        #email CSV file into a single file

                        $emailCol = Get-Content "C:\files\temp\emailOnly.csv" 
                        | Select-Object -skip 1
                        $nameCol = Get-Content "C:\files\temp\nameOnly.csv" | 
                        Select-Object -skip 1

                        # Max function to find the larger count of the two 
                        #csvs to use as the boundary for the counter.
                        $count = [math]::Max($emailCol.count,$nameCol.count)

                        $CombinedArray = for ($i = 0; $i -lt $count; $i++)  {
                                                    [PSCustomObject]@{
                                                    fullName = $nameCol[$i]
                                                    email = $emailCol[$i]
                                                                     }
                                                                            }

                        $CombinedArray | Export-Csv C:\files\temp\revised.csv 
                        -NoTypeInformation

                        }

【问题讨论】:

    标签: arrays powershell csv multiple-columns


    【解决方案1】:

    for loop 更适合您的循环。然后使用计数器作为每个数组的索引来构建您的新对象。

    $emailCol = Get-Content "C:\files\temp\emailOnly.csv" | Select-Object -Skip 2
    $nameCol = Get-Content "C:\files\temp\nameOnly.csv" | Select-Object -Skip 1
    
    # Max function to find the larger count of the two csvs to use as the boundary for the counter.
    $count = [math]::Max($emailCol.count,$nameCol.count)
    $CombinedArray = for ($i = 0; $i -lt $count; $i++) {
        [PSCustomObject]@{
            Name = $nameCol[$i]
            Email = $emailCol[$i]
        }
    }
    $CombinedArray | Export-Csv C:\files\temp\revised.csv -NoTypeInformation
    

    答案已编辑为使用 Get-Content 并添加了额外的跳过以跳过标题行以处理空白行。

    【讨论】:

    • 太棒了!这增加了更多的进步!但是,每行数据中的对象以这种方式显示: Name Email @{displayName=Administrator} @{email=Snookie@NJ.org} 此外,其中一个用户没有分配电子邮件,因此需要跳过他们.但是,您的代码会导致电子邮件行跳过空白行,从而将其余用户对应的电子邮件丢弃。
    • @LilithMae 也许最好先展示你的 CSV 文件中的样本部分,然后解释你真正想要的所有细微差别?
    • @LilithMae 答案已更新,要摆脱 @{email=,您将使用与 csv 中的标头匹配的属性。例如Name = $nameCol.DisplayName[$i] 但是,仅使用 Get-Content 也可以解决您的空行问题。
    • @BenH 这效果很好!感谢您的所有帮助 :) 在等待您的回复时,我意识到我之前运行的一些脚本会导致删除空白行。在我修改了那个脚本之后,这个就起作用了。我已经用对我有用的方法更新了我的问题 :) 非常感谢,祝你有美好的一天。
    【解决方案2】:

    为避免出现有关此主题的其他问题,让我向您展示替代方法。如果您的两个 CSV 文件具有相同的行数,并且第一个文件的每一行对应于第二个文件的第一行等等,那么您可以执行下一步。例如 users.csv:

    User
    Name1
    Name2
    Name3
    Name4
    Name5
    

    和 email.csv:

    Email
    mail1@gmail.com
    mail2@gmail.com
    mail3@gmail.com
    
    mail5@gmail.com
    

    我们的宗旨:

    "User","Email"
    "Name1","mail1@gmail.com"
    "Name2","mail2@gmail.com"
    "Name3","mail3@gmail.com"
    "Name4",
    "Name5","mail5@gmail.com"
    

    我们做什么?

    $c1 = 'C:\path\to\user.csv'
    $c2 = 'C:\path\to\email.csv'
    [Linq.Enumerable]::Zip(
      (Get-Content $c1), (Get-Content $c2),[Func[Object, Object, Object[]]]{$args -join ','}
    ) | ConvertFrom-Csv | Export-Csv C:\path\to\output.csv
    

    如果我们的目的是:

    "User","Email"
    "Name1","mail1@gmail.com"
    "Name2","mail2@gmail.com"
    "Name3","mail3@gmail.com"
    "Name5","mail5@gmail.com"
    

    然后:

    $c1 = 'C:\path\to\user.csv'
    $c2 = 'C:\path\to\email.csv'
    ([Linq.Enumerable]::Zip(
      (Get-Content $c1), (Get-Content $c2),[Func[Object, Object, Object[]]]{$args -join ','}
    ) | ConvertFrom-Csv).Where{$_.Email} | Export-Csv C:\path\to\output.csv
    

    希望这对您将来有所帮助。

    【讨论】:

    • 哇!感谢@greg 的提示!
    • 太好了,我喜欢 PS 中的 Linq-Adaptions
    猜你喜欢
    • 2023-03-27
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    相关资源
    最近更新 更多