0

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

我有一个看起来像这样的大文件:

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...' 附加到第一个文件中,就像join type=left使用 sql

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

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 进行排序,然后编写一些脚本,但由于它不是数字,我不知道如何处理。

非常感谢您的帮助,

4

3 回答 3

2

使用以 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
于 2013-08-29T18:14:26.710 回答
1

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

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
于 2013-08-29T18:21:00.770 回答
0

如果你想做一个LEFT JOIN,你可以将文件加载到一个临时数据库中,然后实际做一个LEFT JOIN. 有关使用SQLite的示例,请参见此处

于 2013-08-30T00:12:42.490 回答