我有两个非常大的.txt文件(大约500 K行)。我需要从两个文件中取出两个列(按列名),并将它们相互比较(类似于左联接在SQL中的工作方式)。因此,我需要将来自第一个文件中不存在的两个列的所有值组合输出到第三个txt/csv文件中。
我需要自动化这个过程,所以我应该能够从命令行调用它。如果有人能给我指明正确的方向,我会非常感激的。
更新文件的格式完全相同,所需的列从不为空。
示例
第一档
DataSource;客户;城市;测绘;SugGroup
艺术;约翰;伦敦;约翰;LondonCustomers
艺术;克里斯;慕尼黑;琼斯;德国
联邦调查局;玛丽;伦敦;詹姆斯;德国
第二档案
DataSource;客户;城市;测绘;SugGroup
艺术;克里斯;慕尼黑;琼斯;德国
联邦调查局;玛丽;伦敦;詹姆斯;德国
我需要做的是采取两栏:客户和映射。并查找第一个文件中的行,而不是第二个文件中的行。因此,在给定的示例中,输出文件如下所示:
输出文件:
客户;测绘
约翰尼
发布于 2014-09-26 12:36:09
我建议不要使用Import-CSV,因为它不能很好地处理100+ Mb范围上的文件。好吧,它很管用,但是狗很慢。
创建一个哈希表。逐行读取第二个文件。缩短这两列并将结果存储在哈希表中。逐行读取第一个文件,并将其两列分开以获得类似的键。检查哈希表是否包含相同的密钥。如果没有,将数据保存到第三个文件中。
对于代码示例,请提供示例输入和期望的输出。
更新:
您没有指定是否可以拥有相同的客户,映射,但更改其他数据。假设不是这样的话,就像这样计算整个行的哈希数,
# Arraylist's initial size 500,000 elemnents
$secondFile = new-object Collections.ArrayList(500000)
# Init MD5 tools
$md5 = new-object Security.Cryptography.MD5CryptoServiceProvider
$utf8 = new-object Text.UTF8Encoding
# Read the 2nd large file
$reader = [IO.File]::OpenText("c:\temp\secondFileBig.txt")
$i=0
while( ($line = $reader.ReadLine()) -ne $null) {
# Get MD5 for each row and store it in the arraylist
$hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($line)))
$secondFile.Add($hash) | out-null
if(++$i % 25000 -eq 0) {write-host -nonewline "."}
}
$reader.Close()
# Sort the arraylist so that it can be binarysearched
$secondFile.Sort()通过使用大约50万行的虚拟数据,在我的计算机上创建散列需要大约50秒。现在,让我们读取另一个文件,并检查它是否具有相同的conent。
# Open and read the file row-vise
$reader = [IO.File]::OpenText("c:\temp\firstFileBig.txt")
while( ($line = $reader.ReadLine()) -ne $null) {
# Get MD5 for current row
$hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($line)))
# If the row already exists in the other file, you'd find its MD5 index with
# binarysearch in O(n log n) time. If found, you'd get zero or larger index
if($secondFile.BinarySearch($hash) -le -1) {
"Not found: $line"
}
}
$reader.Close()使用虚拟测试数据运行第二部分要快得多,可以在Measure-Command中找到答案。它是留给读者的练习,以找出如何提取相关的元素。
https://stackoverflow.com/questions/26059159
复制相似问题