Как я могу использовать sed () заменить все \ r \ n другой escape-последовательностью конца строки? - PullRequest
2 голосов
/ 27 февраля 2020

Итак, я пытаюсь загрузить данные в MySQL, используя LOAD DATA LOCAL INFILE. Около 2 400 000 строк.

Некоторые из этих строк имеют строки с разрывами строк внутри данных и не вставляются.

В одном мы уверены, что последний символ перед фактическим переводом строки - " (двойная кавычка), поэтому мы можем изменить все разрывы строк рядом с " на что-то вроде "***\r\n.

Это позволит мне добавить оператор LINES TERMINATED BY '***\r\n' вместо \r\n

Например,

Одна запись в моем входном файле: in.csv (строка заканчивается \ r \ n)

1,223,"{...}","Some title with

line breaks"\r\n

Требуется вывод после обработки файла :

1,223,"{...}","Some title with

line breaks"***\r\n
`

В качестве альтернативы можно было бы удалить все разрывы строк в данных CSV и иметь только разрывы строк в конце строки. Проблема в том, что я не уверен, как сделать это достаточно быстро, так как я имею дело с действительно большими файлами (2 ГБ +)

Теперь я попытался SED безуспешно. Я думаю, что что-то упустил. Вот моя ближайшая попытка.

sed ':a;N;$!ba;s/"$/***"\r\n/g' in.csv > out.csv

Однако, у меня это не сработало.

Спасибо.

*** ОБНОВЛЕНИЕ ** *

Я понял, что все записи вставляются по запросу данных загрузки. Я думал иначе, потому что счетчик строк с использованием wc-l отличался от select count(*).

Тогда я понял, что когда w c -l встречает данные со встроенными переносами строк, он рассматривает их как отдельную строку вместо того, чтобы рассматривать их как часть одной строки.

Благодарю вас все за ваши усилия.

Ответы [ 2 ]

2 голосов
/ 27 февраля 2020

Вы должны иметь в виду, что $ соответствует только символу новой строки, LF, char. У вас есть возврат каретки до новой строки.

Итак, вам нужно убедиться, что вы соответствуете " либо перед новой строкой, либо перед CRLF:

sed -E ':a;N;$!ba;s/"\r?$/***"\r\n/g' in.csv > out.csv

Здесь паттерн POSIX ERE "\r?$ соответствует " char, затем необязательный возврат каретки, а затем устанавливается позиция в конце строки.

Проверка текстового файла в кодировке UTF8 с окончаниями CRLF

enter image description here

выход

enter image description here

1 голос
/ 27 февраля 2020

Вот скрипт PHP, который должен соответствовать вашим потребностям:

$fin = fopen("input.txt", "r");
$fout = fopen("output.txt", "w");

while(!feof($fin)) {
    $line = preg_replace("/(?<!\")\r?\n/", "", fgets($fin));
    fwrite($fout, $line);
}

fclose($fin);
fclose($fout);

Это решение использует шаблон регулярных выражений (?<!\")\r?\n для цели CR? LF, только если он не следует сразу же после двойной кавычки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...