【问题标题】:sqlite3 import with quotessqlite3 带引号导入
【发布时间】:2013-03-04 22:36:11
【问题描述】:

我正在尝试导入在字段中包含引号的数据集合。它们目前是制表符分隔的。

根据我对文档 (http://www.sqlite.org/cvstrac/wiki?p=ImportingFiles) 的理解,sqlite shell 应该按字面意思解释引号,我认为这意味着我不应该有问题。

我在这条线上遇到了一个问题:

1193782372  Lips Like Sugar (12" Mix)   Echo & the Bunnymen 80's/12": The Extended Collection   a76d9b04-51d9-4672-801f-356ab36dbae7    ccd4879c-5e88-4385-b131-bf65296bf245    1abb270a-e791-407f-a989-ff3ad6f8401c

由于不清楚标签的位置,我将它们包含在以下行中。

1193782372\tLips Like Sugar (12" Mix)\tEcho & the Bunnymen\t80's/12": The Extended Collection\ta76d9b04-51d9-4672-801f-356ab36dbae7\tccd4879c-5e88-4385-b131-bf65296bf245\t1abb270a-e791-407f-a989-ff3ad6f8401c

我正在尝试执行以下操作,但出现错误。

sqlite> .separator \t
sqlite> .import ./file.txt table
Error: ./file.txt line n: expected 7 columns of data but found 5

它可以不带双引号,但引号很重要。我似乎也无法用\" 转义引号。

如何正确导入我想要的数据?

【问题讨论】:

    标签: sqlite tsv


    【解决方案1】:

    Sqlite3 的 .import 工具的行为就好像它的输入是逗号分隔值格式,即使 .separator 不是逗号。您可以通过将引号 (") 加倍 ("") 来转义引号 (")引用它们所在的整个字段。

    在通过以下过滤器运行测试数据后,我得到了一个干净的 .import:

    sed 's/"/""/g;s/[^\t]*/"&"/g' file.txt >quoted.txt
    

    【讨论】:

    • 不错的解决方案!只是想指出mac上的sed似乎不能处理制表符(\t)所以我使用ANSI-C风格的引用,在$前面加上它也适用于mac:sed $'s/"/""/g;s/[^\t]*/"&"/g' file.txt >quoted.txt
    【解决方案2】:

    sqlite3 命令行工具在它支持的导入格式方面不是很灵活。

    你可以

    • 更改导入文件以添加双引号并在字段中转义双引号;或
    • 将导入文件转换成一系列SQL语句:

      INSERT INTO MyTable VALUES(
          1193782372,
          'Lips Like Sugar (12" Mix)',
          'Echo & the Bunnymen 80''s/12": The Extended Collection',
          'a76d9b04-51d9-4672-801f-356ab36dbae7',
          'ccd4879c-5e88-4385-b131-bf65296bf245',
          '1abb270a-e791-407f-a989-ff3ad6f8401c');
      

    • 编写您自己的导入工具。

    【讨论】:

      【解决方案3】:

      您引用的网页是旧的(注意 URL 的 cvstrac 部分,这是赠品;sqlite 现在使用化石,而不是 cvs)。该网页的较新版本是here

      由于 SQLite 是公共领域软件,解决您的问题的一种方法是修复 sqlite 的 shell.c 以正确处理您的文件格式。问题出在第 1861 行左右

      if( c=='"' ) inQuote = !inQuote;
      

      如果您不想使用引号分隔,只需注释掉这一行。该行的目的是让您可以通过引用列在列中嵌入分隔符。

      另一种方法是使用支持 SQLite 的数据库管理器;其中有很多,并且大多数都声称支持文件导入/导出。

      【讨论】:

      • 这个答案已经过时了;我在 shell.c 上找不到您所指的第 1861 行。
      【解决方案4】:

      要在不更改输入数据或 sqlite 源代码的情况下执行此操作,请使用 ascii 模式并将列分隔符设置为制表符,将行分隔符设置为 CRLF (windows) 或 "\n" (*nix)。

      窗口:

      sqlite> .mode ascii
      sqlite> .separator "\t" "\r\n"
      sqlite> .import ./file.txt table
      

      *尼克斯

      sqlite> .mode ascii
      sqlite> .separator "\t" "\n"
      sqlite> .import ./file.txt table
      

      请参阅 my answer to this question 了解原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-13
        • 1970-01-01
        • 1970-01-01
        • 2018-05-09
        • 1970-01-01
        相关资源
        最近更新 更多