首页 > 解决方案 > 如何将 NON-CSV-DELIMITED ASCII 数据导入 SQLite 3?

问题描述

如何将非 CSV ASCII 数据导入 SQLite 3?

我有大量以换行符 (0x0A) 结尾的 ASCII 数据要导入 SQLite 3。我不能使用 CSV 格式,因为许多文本字段都嵌入了逗号和引号。我可以以任何方式重新格式化数据,但我宁愿不重新格式化为 SQL 插入语句(超过 4 亿行)。

我想要使​​用“.import”命令,它应该支持“ascii”格式,其中使用 0x1F 的列分隔符和 0x1E 的行分隔符。不知何故,它不起作用。我不断收到“预期 120 列,但找到 1”。

我得到的所有谷歌结果都是关于 CSV 导入的,这就是我在这里问的原因。

我在下面包含了我的问题的简化示例。如前所述,示例数据可以包含引号(单引号和双引号)、制表符和逗号,因此我不能将它们用作分隔符。我可以为列和行分隔符使用任何其他字节值。

例子。

桌子

create table testtable ( item char(20), descr char(30), misc char(40) );

数据

物品 描述 杂项
苹果 一个水果 暂时没有“其他”评论
葡萄 另一种水果 是的,我喜欢葡萄

标签: sqlite

解决方案


背景

如果 CSV 具有 ( ,, \n) 分别用于 awk 术语字段和记录分隔符,或列和行分隔符,Sqlite.import --ascii [file] [db]期望 ( \x37, \x36) 是标准的 ASCII 单元分隔符 (us) 和记录分隔符 (rs)。见man ascii或其他参考。

演示

使用 获取一个简单的示例 CSV seq 9 | rs -C, 3 | sed 's/,$//' | tee seq.csv,注意没有尾随列分隔符。

<seq.csv tr ',' '\037' | tr '\n' '\036' | tee seq.ascii | less -RF将 CSV 行和列分隔符分别转换为 ASCII 单元和记录分隔符。

sqlite3 seq.db '.import --ascii seq.ascii tbl'进口。

sqlite3 seq.db '.dump tbl'显示导入的表。

其他提示

在 sqlite 中,如果 .import 之前的表不存在,则第一行将成为表头。表需要列名。

在处理其他大文件时less -Rhead -c [char #s]、 和vim可能是您处理这些文件和预览更改的朋友。

我发现引用比我想理解的更挑剔。bash 或命令在某些情况下解释转义序列。tr正确接受$'\x1f'and '\037',但不是"\x1f"。注意 tr 接受 multichar 参数,所以引用是必不可少的,tr , \x1fvstr , '\x1f'有所作为。gnu-sed 增加了解释的后期阶段。

其他选定的参考资料

$ printf "\036\037 \x1e\x1f" | xxd
00000000: 1e1f 201e 1f                             .. ..

man ascii,

  • 八进制:

    034 fs 035 gs 036 rs 037 us

  • 和十六进制:

    1c fs 1d gs 1e rs 1f us.

Sqlite 还允许指定其他列和可选的行分隔符。 .separator COL ?ROW? Change the column and row separators


推荐阅读