用于将列追加到大型CSV文件的工具(按列合并CSV文件)

时间:2019-06-24 21:47:36

标签: python c perl csv utilities

要创建两个csv文件:

echo -e "123\n456" > t0.txt
echo -e '"foo","bar"\n"foo\"bar\"","baz"' > t1.txt

现在,我想将t1.txt中的列追加到t0.txt,以便结果变为:

123,"foo","bar"
456,"foo\"bar\"","baz"

首先尝试使用csvtool

csvtool paste t0.txt t1.txt 
Fatal error: exception Csv.Failure(2, 1, "Bad '"' in quoted field")

因此,csvtool似乎没有处理"foo\"bar\""中的转义引号。

我的实际用例有两个CSV文件,它们具有+150.000.000行和11列,因此我需要一个可以完成任务而又不将所有数据同时存储在RAM中的工具。

csvtool可以与转义引号一起使用,还是有其他工具可以解决此问题?

CSV文件的最终目标是mariadb中的数据库,因此直接使用mariadbt0.txtt1.txt的有效导入会更好,但是据我所知LOAD DATA INFILE仅适用于单个CSV文件。

我绝对更喜欢现成的工具,但是如果没有现成的工具,那么也会喜欢一些C,Perl或Python代码段。

2 个答案:

答案 0 :(得分:2)

这是一个快速的perl脚本,可一次性读取损坏的CSV文件,合并它们并输出正确的转义CSV:

#!/usr/bin/env perl
use warnings;
use strict;
use autodie;
# Install through your OS package manager or CPAN client.
# libtext-csv-xs-perl on Debian/Ubuntu and family.
use Text::CSV_XS; 

open my $file0, "<", $ARGV[0];
open my $file1, "<", $ARGV[1];

my $csv = Text::CSV_XS->new({ binary => 1, escape_char => "\\",
                              auto_diag => 2, strict => 0});
my $out = Text::CSV_XS->new({ binary => 1 });

while ((my $row0 = $csv->getline($file0)) &&
       (my $row1 = $csv->getline($file1))) {
  push @$row0, @$row1;
  $out->say(\*STDOUT, $row0);
}

示例:

$ perl mergecsv.pl t0.txt t1.txt
123,foo,bar
456,"foo""bar""",baz

答案 1 :(得分:1)

CSV文件通常通过重复(""而不是\"来引起双引号,因此您的文件可以被视为无效。

您可以使用查找和替换工具(例如Unix上的sed)将转义的引号固定为这种更常见的格式。

如果您要使用其他命令行工具来处理CSV文件,我已经编写了一个https://github.com/pjshumphreys/querycsv可用的工具