【发布时间】:2021-02-15 00:48:28
【问题描述】:
我需要使用 Powershell 或 Perl(公司请求)对一些巨大的(2GB 或更多)CSV 文件进行排序。 我需要从任何列中对它们进行排序,具体取决于文件。
对于某些人来说,我的 CSV 文件看起来像这样,使用 双引号:
Column1;Column2;Column3;Column4
1234;1234;ABCD;"1234;ABCD"
5678;5678;ABCD;"5678;ABCD"
9012;5678;ABCD;"9012;ABCD"
...
在 Powershell 中,我已经测试了解决方案 Import-CSV,但我遇到了 OutOfMemory Exception 问题。 我还尝试使用 OleDb Connection 使用以下代码将我的 CSV 文件加载到 SQL 表中:
$provider = (New-Object System.Data.OleDb.OleDbEnumerator).GetElements() | Where-Object { $_.SOURCES_NAME -like "Microsoft.ACE.OLEDB.*" }
if ($provider -is [system.array]) { $provider = $provider[0].SOURCES_NAME } else { $provider = $provider.SOURCES_NAME }
$csv = "PathToCSV\file.csv"
$firstRowColumnNames = "Yes"
$connstring = "Provider=$provider;Data Source=$(Split-Path $csv);Extended Properties='text;HDR=$firstRowColumnNames;';"
$tablename = (Split-Path $csv -leaf).Replace(".","#")
$sql = "SELECT * from [$tablename] ORDER BY Column3"
# Setup connection and command
$conn = New-Object System.Data.OleDb.OleDbconnection
$conn.ConnectionString = $connstring
$conn.Open()
$cmd = New-Object System.Data.OleDB.OleDBCommand
$cmd.Connection = $conn
$cmd.CommandText = $sql
$cmd.ExecuteReader()
# Clean up
$cmd.dispose
$conn.dispose
但这会给我返回错误:
Exception calling "ExecuteReader" with "1" argument(s): "No value given for one or more required parameters." 我不明白为什么。我试过修改代码,SQL代码,还是不行。
我认为这是做到这一点的最佳解决方案,但我暂时无法让它发挥作用,我对所有其他可行的解决方案持开放态度......
我是 Perl 的初学者,所以我只是想了解它的工作原理以及如何使用它,但暂时没有编写任何代码。
编辑
我刚刚测试了您提出的所有解决方案,非常感谢您的帮助。
两种解决方案均无效,因为您告诉我使用的模块(Text::CSV、File::Sort 或 Data::Dumper)未安装在我使用的 Perl 版本中,我无法安装他们(公司限制......)。
我尝试的是对列进行简单排序,而不考虑 双引号 问题:
use CGI qw(:standard);
use strict;
use warnings;
my $file = 'path\to\my\file.csv';
open (my $csv, '<', $file) || die "cant open";
foreach (<$csv>) {
chomp;
my @fields = split(/\;/);
}
@sorted = sort { $a->[1] cmp $b->[1] } @fields;
我在想这应该可行,在我的数组中排序@sorted 我在第二列的数据,但它不起作用,我不明白为什么......
【问题讨论】:
-
@A Le Drian 推荐在 Perl 中读取 CSV 文件的模块是 Text::CSV_XS。读取 CSV 数据后,将其存储在具有唯一值作为键的哈希中,然后使用
sort函数轻松打印。 -
@vkk05 读取CSV数据会不会有内存问题?
-
它是用python编写的,但我会先从csvkit尝试
csvsort。 -
如果内存有问题,您可以将整个 CSV 文件加载到 SQLite 中,然后编写一个生成排序输出的查询。引号并不重要。正确实现的消费者会在需要的地方用引号和不带引号来理解它。
-
您考虑过使用 Excel 吗?您似乎在 Windows 上,这可能是最好的选择。
标签: powershell csv perl sorting