如何使用linux将大型csv拆分成多个小型csv?

时间:2014-08-11 10:22:06

标签: linux csv split

需要使用php和linux将大型csv文件拆分为多个文件。

CSV包含 -

"id","name","address"
"1","abc","this is test address1 which having multiple  newline
separators."
"2","abc","this is test address2
which having multiple newline  separators"
"3","abc","this is test address3.
which having multiple
newline separators."

我使用了linux comand - split -l 5000 testfile。

但是它无法以正确的格式拆分csv,因为在csv中有一个字段地址有多个换行符,所以命令用来自该行的拆分文件。

我也尝试过使用PHP:

$inputFile = 'filename.csv';
$outputFile = "outputfile";
$splitSize = 5000;
$in = fopen($inputFile, 'r'):
$header = fgetcsv($in);
$rowCount = 0;
$fileCount = 1;

while (!feof($in)) { 
    if (($rowCount % $splitSize) == 0) {
        if ($rowCount > 0) {
            fclose($out);
        }   
        $filename = $outputFile . $fileCount++;
        $out = fopen($filename .'.csv', 'w');
        chmod($filename,777);
        fputcsv($out, $header);
    }   
    $data = fgetcsv($in);
    if ($data) {
        fputcsv($out, $data);
        $rowCount++;
    }   
}
fclose($out);

如何解决此问题?

2 个答案:

答案 0 :(得分:1)

使用Ruby:

ruby -e 'require "csv"
        f = ARGV.shift
        CSV.foreach(f).with_index{ |e, i|
            File.write("#{f}.#{i}", CSV.generate_line(e, force_quotes: true))
        }' file.csv

腓:

<?php
    $inputFile = 'file.csv';
    $outputFile = 'file.out';
    $splitSize = 1;
    if (($in = fopen($inputFile, 'r'))) {
        $header = fgetcsv($in);
        $rowCount = 0;
        $fileCount = 0;
        while (($data = fgetcsv($in))) {
            if (($rowCount % $splitSize) == 0) {
                if ($rowCount > 0) {
                    fclose($out);
                }
                $filename = $outputFile . ++$fileCount . '.csv';
                $out = fopen($filename, 'w');
                chmod($filename, 755);
                fputcsv($out, $header);
            }
            fputcsv($out, $data);
            $rowCount++;
        }
        fclose($out);
    }
?>

答案 1 :(得分:1)

Linux有一个很棒的小实用程序叫做split,可以将文件分割成你想要的任何大小的块,例如100行块。

但是,对于CSV文件等,每个块通常需要在那里有标题行。不幸的是,split命令没有选项。但是,如果有更多的代码,你就可以实现它。

tail -n +2 file.txt | split -l 4 - split_
for file in split_*
do
head -n 1 file.txt > tmp_file
cat $file >> tmp_file
mv -f tmp_file $file
done