16

MySQL 有一个不错的 CSV 导入功能LOAD DATA INFILE

我有一个需要定期从 CSV 导入的大型数据集,所以这个功能正是我所需要的。我有一个可以完美导入数据的工作脚本。

.....除了....我事先不知道行尾终止符是什么。

我的 SQL 代码目前看起来像这样:

LOAD DATA INFILE '{fileName}'
 INTO TABLE {importTable}
 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
 LINES TERMINATED BY '\n'
 IGNORE 1 LINES
( {fieldList} );

这对于某些导入文件非常有用。

但是,导入数据来自多个来源。其中一些有\n终止符;其他人有\r\n。我无法预测我会拥有哪一个。

有没有一种方法可以LOAD DATA INFILE用来指定我的行可以用\n或终止\r\n?我该如何处理?

4

7 回答 7

11

您可以将行分隔符指定为 '\n' 并在加载期间从最后一个字段中删除尾随的 '\r' 分隔符。

例如 -

假设我们有“entries.txt”文件。行分隔符是 '\r\n',只有行之后ITEM2 | CLASS3 | DATE2的分隔符是 '\n':

COL1  | COL2   | COL3
ITEM1 | CLASS1 | DATE1
ITEM2 | CLASS3 | DATE2
ITEM3 | CLASS1 | DATE3
ITEM4 | CLASS2 | DATE4

创建表语句:

CREATE TABLE entries(
  column1 VARCHAR(255) DEFAULT NULL,
  column2 VARCHAR(255) DEFAULT NULL,
  column3 VARCHAR(255) DEFAULT NULL
)

我们的 LOAD DATA INFILE 查询:

LOAD DATA INFILE 'entries.txt' INTO TABLE entries
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(column1, column2, @var)
SET column3 = TRIM(TRAILING '\r' FROM @var);

显示结果:

SELECT * FROM entries;
+---------+----------+---------+
| column1 | column2  | column3 |
+---------+----------+---------+
| ITEM1   |  CLASS1  |  DATE1  |
| ITEM2   |  CLASS3  |  DATE2  |
| ITEM3   |  CLASS1  |  DATE3  |
| ITEM4   |  CLASS2  |  DATE4  |
+---------+----------+---------+
于 2012-06-12T11:12:22.200 回答
10

我只是预处理它。作为导入过程的一部分,从命令行工具将 \r\n 更改为 \n 的全局搜索/替换应该简单且高效。

于 2012-06-07T16:18:31.263 回答
3

我假设您只需要通过 mysql 而不是任何编程语言来获取信息。如果您有记事本++,则在使用加载数据之前将格式转换为windows 格式\r\n ( CR LF )。然后处理Load数据查询。确保 LINES TERMINATED BY '\r\n'

在此处输入图像描述

编辑:

由于编辑器通常不适合转换较大的文件。对于较大的文件,以下命令通常用于 windows 和 linux

1)在windows中转换成windows格式

TYPE [unix_file] | FIND "" /V > dos_file

2)在linux中转换成windows格式

unix2dos  [file]

其他命令也可用

windows 格式文件可以通过 tr -d '\r' < inputfile > outputfile删除所有 ASCII CR \r字符转换为 Unix 格式

grep -PL $'\r\n' myfile.txt # show UNIX format  style file (LF terminated)
grep -Pl $'\r\n' myfile.txt # show WINDOS format style file (CRLF terminated)

在 linux/unix 中,file命令检测所使用的行尾 (EOL) 类型。因此可以使用此命令检查文件类型

于 2012-06-12T06:47:54.547 回答
1

您还可以查看其中一个数据集成包。Talend Open Studio 具有非常灵活的数据输入例程。例如,您可以使用一组分隔符处理文件并捕获拒绝并以另一种方式处理它们。

于 2012-06-07T17:44:12.030 回答
1

如果第一次加载有 0 行,则对另一个行终止符执行相同的语句。这应该可以通过一些基本的计数逻辑来实现。

至少它全部保留在 SQL 中,如果它在你第一次获胜时工作。并且可以减少重新扫描所有行并删除特定字符的头痛。

于 2012-06-12T21:05:59.007 回答
1

为什么不先看看线条是如何结束的?

$handle = fopen('inputFile.csv', 'r');

$i = 0;
if ($handle) {
    while (($buffer = fgets($handle)) !== false) {

        $s =  substr($buffer,-50);

        echo $s; 
        echo preg_match('/\r/', $s) ? 'cr ' : '-- ';
        echo preg_match('/\n/', $s) ? 'nl<br>' : '--<br>';          

        if( $i++ > 5)
            break;

    }

    fclose($handle);
}
于 2013-11-05T03:50:06.620 回答
0

您可以使用 LINES STARTING 将文本中的常用行结尾和新行分开:

LOAD DATA LOCAL INFILE '/home/laptop/Downloads/field3-utf8.csv' 
IGNORE INTO TABLE Field FIELDS 
TERMINATED BY ';' 
OPTIONALLY ENCLOSED BY '^' 
LINES STARTING BY '^' 
TERMINATED BY '\r\n' 
(Id, Form_id, Name, Value)

对于带有 " 封闭字符的普通 CSV 文件,它将是:

...
LINES STARTING BY '"' 
...
于 2018-07-20T07:56:03.990 回答