【问题标题】:Join two files in powershell在powershell中加入两个文件
【发布时间】:2013-08-29 16:37:00
【问题描述】:

真的需要这方面的帮助:(我会尽量简单。

我有一个大文件,如下所示:

ID,Info1,Info2,info3,...

在每一行,我都有一个 ID 和很多东西,用逗号分隔。可以有 > 3000 行。

现在我得到了第二个这样的文件:

ID,Info4,Info5,Info6,...

第一个文件包含所有元素,而第二个文件只包含其中的一部分。

比如第一个:

BLA1,some stuff...
BLA2,some stuff...
BLA3,some stuff...
ALO1,some stuff...
ALO2,some stuff...

第二个:¨

BLA3,some stuff2... 
ALO1,some stuff2...
BLA1,some stuff2... 

我想要的很简单,我想将第二个文件的所有 'some stuff2...' 附加到第一个文件中,例如带有 sql 的 join type=left

我希望现在有第一个文件:

BLA1,some stuff...,some stuff2...
BLA2,some stuff...
BLA3,some stuff...,some stuff2...
ALO1,some stuff...,some stuff2...
ALO2,some stuff...

我试过这样的:

ForEach ($line in $file1) {
    $colA = $line.Split(',')
    ForEach ($line in $file2) {
        $colB = $line.Split(',')
        if($colA[0]-eq $colB[0]) { #Item found in file2
            $out += $date + $colA[1]+","+ ... +","+ $colB[1]+","+ ... +"`n"
        }else { 
            $out += $date + $colA[1]+","+ ... +"`n"
        }
    }
}

但是它需要很长时间才能成功(也许还有其他我没有看到的问题)。最好的方法是什么?二维数组?我可以尝试对 ID 进行排序,然后编写一些脚本,但由于它不是数字,我不知道如何处理。

非常感谢您的帮助,

【问题讨论】:

    标签: arrays file powershell join


    【解决方案1】:

    使用以 ID 为键的哈希表。

    $ht = [ordered]@{}
    foreach ($line in $file1) {
        $id,$rest = $line -split ',',2
        $ht[$id] = $line
    }
    foreach ($line in $file2) {
        $id,$rest = $line -split ',',2
        if ($ht.ContainsKey($id)) {
            $ht[$id] += ",$rest"
        }
        else {
            $ht[$id] = $line
        }
    }
    $ht.Values > newfile.txt
    

    【讨论】:

    • 啊,如果我不使用 $rest,ID 现在是一个数组。好点,我会更新脚本。谢谢。
    • 我必须使用 Powershell v2。所以我删除了我认为没有必要的 [ordered]?,我需要找到一种方法来编写 hastable 原因 $ht.Values 返回 System.Collections.Hashtable+ValueCollection
    • $ht.Values 是另一个 V3 主义。试试$ht.GetEnumerator() | Foreach {$_.Value}
    【解决方案2】:

    我假设您知道标题行或可以添加它们...

    f1.csv

    Name,Item_1
    BLA1,thing_bla1_1
    ALB1,thing_alb1_1
    BLA2,thing_bla2_1
    ALB2,thing_alb2_1
    BLA3,thing_bla3_1
    ALB3,thing_alb3_1
    

    f2.csv

    Name,Item_2
    BLA3,thing_bla3_2
    ALB3,thing_alb3_2
    BLA1,thing_bla1_2
    ALB1,thing_alb1_2
    BLA2,thing_bla2_2
    ALB2,thing_alb2_2
    

    代码:

    $grouped = Import-Csv .\f1.csv, .\f2.csv | group -property Name -ashashtable
    
    $($grouped.Keys | foreach {$obj = $grouped.Item("$_")[0].Name + "," + $grouped.Item("$_")[0].Item_1 + "," + $grouped.Item("$_")[1].Item_2; $obj}) | Out-File .\test.csv
    

    我们在这里所做的是将两个 CSV 导入到一个元素中,然后将哈希表中的同名项目分组。然后我们将键(文件中的非重复名称)通过管道传输到一个 foreach 中,将它们组合成一行。我们需要这些语句周围的 $() 以允许将输出通过管道传输到 Out-File。

    我几乎肯定有一种更清洁的方式来处理 foreach 的内部,但这确实有效。

    输出(text.csv):

    ALB1,thing_alb1_1,thing_alb1_2
    BLA2,thing_bla2_1,thing_bla2_2
    ALB3,thing_alb3_1,thing_alb3_2
    BLA1,thing_bla1_1,thing_bla1_2
    ALB2,thing_alb2_1,thing_alb2_2
    BLA3,thing_bla3_1,thing_bla3_2
    

    【讨论】:

      【解决方案3】:

      如果您想执行LEFT JOIN,您可以将文件加载到临时数据库中并实际执行LEFT JOIN。有关使用 SQLite 的示例,请参阅 here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-10
        • 2020-03-10
        • 2023-03-16
        • 2017-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-19
        相关资源
        最近更新 更多