⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
导入 Duckbox 表

此页面中提供的脚本适用于 Linux、macOS 和 WSL。

默认情况下,DuckDB CLI 客户端duckbox 格式呈现查询结果,该格式使用丰富的、ASCII 艺术风格的表格来显示数据。这些表格经常被原样分享到其他文档中。例如,以下表格用于演示 DuckDB v1.2.0 发布博客文章中新的 CSV 功能

┌─────────┬───────┐
│    a    │   b   │
│ varchar │ int64 │
├─────────┼───────┤
│ hello   │    42 │
│ world   │    84 │
└─────────┴───────┘

如果我们想将这些数据重新加载到 DuckDB 中怎么办?默认情况下不支持此操作,但可以通过一些脚本实现:我们可以将表格转换为以 分隔的文件,然后使用 DuckDB 的 CSV 读取器读取。请注意,分隔符不是管道符 |,而是 “Box Drawings Light Vertical” 字符

将 Duckbox 表格加载到 DuckDB

首先,我们将上面的表格保存为 duckbox.csv。然后,我们使用 sed 清理它

echo -n > duckbox-cleaned.csv
sed -n "2s/^│ *//;s/ *│$//;s/ *│ */│/p;2q" duckbox.csv >> duckbox-cleaned.csv
sed "1,4d;\$d;s/^│ *//;s/ *│$//;s/ *│ */│/g" duckbox.csv >> duckbox-cleaned.csv

清理后的 duckbox-cleaned.csv 文件如下所示

a│b
hello│42
world│84

然后我们可以简单地将其加载到 DuckDB 中,方法是

FROM read_csv('duckbox-cleaned.csv', delim = '│');

并将其导出为 CSV

COPY (FROM read_csv('duckbox-cleaned.csv', delim = '│')) TO 'out.csv';
a,b
hello,42
world,84

使用 shellfs

为了通过单个 read_csv 调用解析 duckbox 表格——并且不创建任何临时文件——我们可以使用 shellfs 社区扩展

INSTALL shellfs FROM community;
LOAD shellfs;
FROM read_csv(
        '(sed -n "2s/^│ *//;s/ *│$//;s/ *│ */│/p;2q" duckbox.csv; ' ||
        'sed "1,4d;\$d;s/^│ *//;s/ *│$//;s/ *│ */│/g" duckbox.csv) |',
        delim = '│'
    );

我们还可以创建一个表宏

CREATE MACRO read_duckbox(path) AS TABLE
    FROM read_csv(
            printf(
                '(sed -n "2s/^│ *//;s/ *│$//;s/ *│ */│/p;2q" %s; ' ||
                'sed "1,4d;\$d;s/^│ *//;s/ *│$//;s/ *│ */│/g" %s) |',
                path, path
            ),
            delim = '│'
        );

然后,读取 duckbox 表格就变得很简单了,只需

FROM read_duckbox('duckbox.csv');

shellfs 是一个社区扩展,不提供任何支持或保证。仅在您能确保其输入经过适当清理的情况下使用它。有关更多详细信息,请查阅保护 DuckDB 页面

限制

运行此脚本时请考虑以下限制

  • 此方法仅适用于表格中没有长管道符 的情况。它还会从表格单元格值中修剪空格。运行脚本时请务必考虑这些假设。

  • 此脚本兼容 BSD sed(macOS 上的默认设置)和 GNU sed(Linux 上的默认设置,在 macOS 上可用作 gsed)。

  • 只有CSV 嗅探器支持的数据类型才能正确解析。包含嵌套数据的值将解析为 VARCHAR