首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当双引号中有\n (行中断)时,如何使用pgloader或PostgreSQL副本解析CSV?

当双引号中有\n (行中断)时,如何使用pgloader或PostgreSQL副本解析CSV?
EN

Stack Overflow用户
提问于 2017-06-07 17:20:08
回答 2查看 1.4K关注 0票数 1

我有一条这样的csv线路:

代码语言:javascript
复制
"aaa"|"bbb"|"ccc"|"dddd
eeeee"

我想使用pgloader (http://pgloader.io/)或PostgreSQL COPY (https://www.postgresql.org/docs/9.6/static/sql-copy.html)导入这些数据。我在这里的问题是,根据CSV标准,在引用的字段值中有一个行间隔(\n)是可能的。但是pgloader和COPY命令将它视为一个全新的数据行,而不是在其中包含行中断的一列。

代码语言:javascript
复制
COPY schema.table (
    col_aaa,
    col_bbb,
    col_ccc,
    col_ddd
) 
    FROM 'file.csv' WITH DELIMITER '|' ENCODING 'LATIN1' CSV;

我的复制命令我的pgloader命令

代码语言:javascript
复制
LOAD CSV
FROM 'file.csv' 
INTO postgresql://user:password@host:5432/database?schema.table (col_aaa, col_bbb, col_ccc, col_ddd)

WITH   
skip header = 0,
fields optionally enclosed by '"',
fields escaped by double-quote,
fields terminated by '|'  

SET client_encoding to 'latin1'
BEFORE LOAD DO
    $$ TRUNCATE anac.aerodromos_csv RESTART IDENTITY; $$;

我从PostgreSQL文档中搜索了很多东西,也从谷歌搜索了很多东西。

我发现的唯一一件事是:Parsing CSV file with \n in double quoted fields但是awk太慢了,对于一个超过100万行的文件来说。

对怎么做有什么建议吗?

我的首选是pgloader,但我可以接受使用sed或perl作为regex代理来处理linux脚本中的文件。

有怎么做的线索吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-21 19:49:33

问题是,在行的末尾有一个\r\n,为了解决这个问题,我只从数据中的行中断中删除\r。

这样,pgloader就能够完成这项工作。

我通过使用一行perl实现了这一点。

代码语言:javascript
复制
perl -0777 -pi -e 's/(?<="[^"|])*(?<!["|])\r\n(?=[^"]*")/\n/smg' $csv_file_name # O -0777 is explained at em https://stackoverflow.com/questions/9670426/perl-command-line-multi-line-replace

Perl command line multi-line replace

票数 0
EN

Stack Overflow用户

发布于 2017-06-08 07:27:26

为了给你一个解决这个问题的想法,我正在写这个例子。

我刚刚假设该文件将只包含4列,并且只包含1行中断。如果不是这样的话,那么您需要改变这种情况。

输入文件:

代码语言:javascript
复制
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"dddd
eeeee"
"aaa"|"bbb"|"cc
c"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"b
bb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"a
aa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"dddd
eeeee"

script.pl

代码语言:javascript
复制
#!/usr/bin/perl
use strict; use warnings; use Data::Dumper;

open ( my $RFH, '<', 'input.io' ) or die ($!);
open ( my $WFH, '>', 'output.o' ) or die ($!);

my $line_break = 0;
my $old_line = '';

while ( my $line = <$RFH> ) {
    chomp($line);
    if ( ! $line_break ){
        my @columns = split( /\|/, $line );
        if ( scalar( @columns ) == 4 && $columns[3] =~ m/"$/ ){
            print $WFH $line."\n";
        }
        else{
            $line_break = 1;
            $old_line = $line;
            next;
        }
    }
    else{
        $line = $old_line . $line;
        $old_line = '';
        $line_break = 0;
        print $WFH $line."\n";
    }
}

close($RFH);
close($WFH);

输出文件:

代码语言:javascript
复制
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"
"aaa"|"bbb"|"ccc"|"ddddeeeee"

将此示例更改为您的需要。希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44419059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档