要创建两个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
中的数据库,因此直接使用mariadb
和t0.txt
到t1.txt
的有效导入会更好,但是据我所知LOAD DATA INFILE
仅适用于单个CSV文件。
我绝对更喜欢现成的工具,但是如果没有现成的工具,那么也会喜欢一些C,Perl或Python代码段。
答案 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可用的工具