加入 2 CSV 的最简单方法(如 SQL LEFT JOIN)
lightest way to join 2 CSV (like an SQL LEFT JOIN)
我依靠社区专业知识来指导我以最好的方式关注主题。
在专业环境下 运行 在 windows 上无法安装 MS-Office 应用程序我需要向我的团队分发一种方法来加入 2 个 CSV 文件并生成第 3 个 CSV 文件作为输出。就像我们 运行 一个 SQL 查询一样:
SELECT f1.*, f1.bar = f2.bar as baz
FROM CSVfile1 as f1
LEFT JOIN CSVfile2 as f2
ON f1.key = f2.key
目标目前已通过 Excel + VBA 实现,但 MS-office 软件包将被删除且无法访问。由于同样的原因,无法设想使用 MS-Access 的解决方案。
目标是允许任何机构在没有任何能力和在其计算机上进行特定安装的情况下实现第三个 CSV。因此,使用 python 或 MS-SQL-Servr 的方法也不好。
我想用 Powshell 脚本来完成,但首先。我不习惯使用PowerShell,但我可以学习。
但在尝试之前,我向社区询问这是否是最好的方法?或者是否有更好的解决方案? (要求:Windows OS(最新版本),无 MS-office,无特定安装)。
谢谢大家
从 v7.2[=42 开始,PowerShell 没有内置连接功能(类似于 SQL 的[1]) =],尽管在 GitHub issue #14994; third-party solutions are available, via the PowerShell Gallery (e.g., JoinModule
) 中提议添加 Join-Object
cmdlet。
目前,如果无法安装第三方工具,您可以推出自己的解决方案,方法如下,该方法使用Import-Csv
to load the CSV files, an auxiliary hashtable to find corresponding rows, and Add-Member
添加列(属性)。
# Create sample CSV files.
$csv2 = @'
key,bar,quux
key1,bar1,quux1
key2,bar2,quux2
key3,bar3,quux3
'@ > ./CSVFile1.csv
@'
key,bar
key1,bar1
key2,bar2a
'@ > ./CSVFile2.csv
# Import the the 2nd file and load its rows
# (as objects with properties reflecting the columns)
# into a hashtable, keyed by the column 'key' values.
$hash = @{}
foreach ($row in Import-Csv ./CSVFile2.csv) {
$hash[$row.key] = $row
}
# Import the 1st file and process each row (object):
# Look for a matching object from the 2nd file and add
# a calculated column derived from both objects to the
# input object.
Import-Csv ./CSVFile1.csv | ForEach-Object {
$matching = $hash[$_.key]
$_ |
Add-Member -PassThru baz $(if ($matching) { [int] ($matching.bar -eq $_.bar) })
}
将最后一条语句通过管道传输到 Export-Csv
,以将生成的对象导出到 CSV 文件。
(例如
... | Export-Csv -NoTypeInformation -Encoding utf8 Results.csv
)
以上结果如下:
key bar quux baz
--- --- ---- ---
key1 bar1 quux1 1
key2 bar2 quux2 0
key3 bar3 quux3
[1]有一个-join
operator,但它的作用是将一个单个数组的元素拼接成一个单串.
这是使用 sqlite 命令行 shell(单个 900kb 可执行文件)和相同的 sql 加入命令的现成答案。 https://sqlite.org/download.html Sqlite 似乎无法处理 utf16 或“unicode”文本文件。即使 Excel 在导入 utf16 csv 时也遇到更多麻烦。
# making csv file with ">" (utf16) caused this error:
# CREATE TABLE csvfile1(...) failed: duplicate column name:
'key,bar,quux
key1,bar1,quux1
key2,bar2,quux2
key3,bar3,quux3' | set-content csvfile1.csv
'key,bar
key1,bar1
key2,bar2a' | set-content csvfile2.csv
'.mode csv
.import csvfile1.csv csvfile1
.import csvfile2.csv csvfile2
.headers on
SELECT f1.*, f1.bar = f2.bar as baz
FROM CSVfile1 as f1
LEFT JOIN CSVfile2 as f2
ON f1.key = f2.key' | .\sqlite3
# output
# key,bar,quux,baz
# key1,bar1,quux1,1
# key2,bar2,quux2,0
# key3,bar3,quux3,
我依靠社区专业知识来指导我以最好的方式关注主题。
在专业环境下 运行 在 windows 上无法安装 MS-Office 应用程序我需要向我的团队分发一种方法来加入 2 个 CSV 文件并生成第 3 个 CSV 文件作为输出。就像我们 运行 一个 SQL 查询一样:
SELECT f1.*, f1.bar = f2.bar as baz
FROM CSVfile1 as f1
LEFT JOIN CSVfile2 as f2
ON f1.key = f2.key
目标目前已通过 Excel + VBA 实现,但 MS-office 软件包将被删除且无法访问。由于同样的原因,无法设想使用 MS-Access 的解决方案。
目标是允许任何机构在没有任何能力和在其计算机上进行特定安装的情况下实现第三个 CSV。因此,使用 python 或 MS-SQL-Servr 的方法也不好。
我想用 Powshell 脚本来完成,但首先。我不习惯使用PowerShell,但我可以学习。
但在尝试之前,我向社区询问这是否是最好的方法?或者是否有更好的解决方案? (要求:Windows OS(最新版本),无 MS-office,无特定安装)。
谢谢大家
从 v7.2[=42 开始,PowerShell 没有内置连接功能(类似于 SQL 的[1]) =],尽管在 GitHub issue #14994; third-party solutions are available, via the PowerShell Gallery (e.g., JoinModule
) 中提议添加 Join-Object
cmdlet。
目前,如果无法安装第三方工具,您可以推出自己的解决方案,方法如下,该方法使用Import-Csv
to load the CSV files, an auxiliary hashtable to find corresponding rows, and Add-Member
添加列(属性)。
# Create sample CSV files.
$csv2 = @'
key,bar,quux
key1,bar1,quux1
key2,bar2,quux2
key3,bar3,quux3
'@ > ./CSVFile1.csv
@'
key,bar
key1,bar1
key2,bar2a
'@ > ./CSVFile2.csv
# Import the the 2nd file and load its rows
# (as objects with properties reflecting the columns)
# into a hashtable, keyed by the column 'key' values.
$hash = @{}
foreach ($row in Import-Csv ./CSVFile2.csv) {
$hash[$row.key] = $row
}
# Import the 1st file and process each row (object):
# Look for a matching object from the 2nd file and add
# a calculated column derived from both objects to the
# input object.
Import-Csv ./CSVFile1.csv | ForEach-Object {
$matching = $hash[$_.key]
$_ |
Add-Member -PassThru baz $(if ($matching) { [int] ($matching.bar -eq $_.bar) })
}
将最后一条语句通过管道传输到 Export-Csv
,以将生成的对象导出到 CSV 文件。
(例如
... | Export-Csv -NoTypeInformation -Encoding utf8 Results.csv
)
以上结果如下:
key bar quux baz
--- --- ---- ---
key1 bar1 quux1 1
key2 bar2 quux2 0
key3 bar3 quux3
[1]有一个-join
operator,但它的作用是将一个单个数组的元素拼接成一个单串.
这是使用 sqlite 命令行 shell(单个 900kb 可执行文件)和相同的 sql 加入命令的现成答案。 https://sqlite.org/download.html Sqlite 似乎无法处理 utf16 或“unicode”文本文件。即使 Excel 在导入 utf16 csv 时也遇到更多麻烦。
# making csv file with ">" (utf16) caused this error:
# CREATE TABLE csvfile1(...) failed: duplicate column name:
'key,bar,quux
key1,bar1,quux1
key2,bar2,quux2
key3,bar3,quux3' | set-content csvfile1.csv
'key,bar
key1,bar1
key2,bar2a' | set-content csvfile2.csv
'.mode csv
.import csvfile1.csv csvfile1
.import csvfile2.csv csvfile2
.headers on
SELECT f1.*, f1.bar = f2.bar as baz
FROM CSVfile1 as f1
LEFT JOIN CSVfile2 as f2
ON f1.key = f2.key' | .\sqlite3
# output
# key,bar,quux,baz
# key1,bar1,quux1,1
# key2,bar2,quux2,0
# key3,bar3,quux3,