MySQL LOAD DATA INFILE: работает, но непредсказуемый Терминатор линии

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 символ; другие rn. Я не могу предсказать, какой я буду.

есть ли способ с помощью LOAD DATA INFILE, чтобы указать, что мои строки могут быть прекращены с n или rn? Как мне с этим справиться?

7 ответов


Я бы просто предварительно обработал его. Глобальный поиск / замена для изменения \r\n на \N из средства командной строки как часть процесса импорта должен быть простым и эффективным.


вы можете указать разделитель строк как "\n "и удалить конечные разделители "\r", если это необходимо, из последнего поля во время загрузки.

например

Предположим, у нас есть записи'.файл 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
)

наш запрос загрузки данных 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  |
+---------+----------+---------+

Я предполагаю, что вам нужна информация только через mysql no на любом языке программирования. Перед использованием load data covert формат до формат windows \r\n (CR LF), если у вас есть notepad++. А затем обработать запрос Load data. Убедитесь, что строки завершены '\r\n'

enter image description here

Edit:

так как редакторы часто не подходят для преобразования больших файлов. Для больших файлов следующая команда: часто используется как windows, так и linux

1) конвертировать в формат windows в windows

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

2) конвертировать в формат windows в linux

unix2dos  [file]

другие команды также доступны

файл формата windows может быть преобразован в формат Unix, просто удалив все ASCII CR \r символы tr-d '\r' outputfile

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 определяет тип используемого конца строки (EOL). Таким образом, тип файла можно проверить с помощью этой команды


вы также можете заглянуть в один из пакетов интеграции данных. Talend Open Studio имеет очень гибкие процедуры ввода данных. Например, вы можете обработать файл с одним набором разделителей и поймать отклонения и обработать их другим способом.


Если первая загрузка имеет 0 строк, выполните ту же инструкцию с другим Терминатором строки. Это должно быть сделано с некоторой базовой логикой подсчета.

по крайней мере, он остается все в SQL, и если он работает в первый раз, когда вы выигрываете. И может вызвать меньше головной боли, что повторное сканирование всех строк и удаление определенного символа.


почему бы сначала не взглянуть на то, как заканчиваются строки?

$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);
}

вы можете использовать строки, начинающиеся с разделения обычных окончаний строк в тексте и новой строки:

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 '"' 
...