Creating multiple csv files from data within a csv file
Perl "one-liner"
perl -MText::CSV_XS -e'$c=Text::CSV_XS->new({binary=>1,eol=>"\n"});%a=map{$i++;/^L\d+$/?($_=>$i):()}@{$c->getline(*ARGV)};open$b{$_},">$_"for keys%a;while($f=$c->getline(*ARGV)){$c->print($b{$_},[@$f[0,1,$a{$_}]])for keys%a}'
For ones which have problem with reading:
$ echo '$c=Te...' | perltidy
$c = Text::CSV_XS->new( { binary => 1, eol => "\n" } );
%a = map { $i++; /^L\d+$/ ? ( $_ => $i ) : () } @{ $c->getline(*ARGV) };
open $b{$_}, ">$_" for keys %a;
while ( $f = $c->getline(*ARGV) ) {
$c->print( $b{$_}, [ @$f[ 0, 1, $a{$_} ] ] )
for keys %a;
}
Using only AWK:
awk -F, -vOFS=, -vc=1 '
NR == 1 {
for (i=1; i<NF; i++) {
if ($i != "") {
g[c]=i;
f[c++]=$i
}
}
}
NR>2 {
for (i=1; i < c; i++) {
print $1,$2, $g[i] > "output_"f[i]".csv"
}
}' data.csv
As a one-liner:
awk -F, -vOFS=, -vc=1 'NR == 1 {for (i=1; i<NF; i++) {if ($i != "") {g[c]=i; f[c++]=$i}}} NR>2 { for (i=1; i < c; i++) {print $1,$2, $g[i] > "file_"f[i]".csv" }}' data.csv
Example output:
$ cat file_L1.csv
EXAMPLEfoo,60,6
EXAMPLEbar,30,6
EXAMPLE1,60,3
EXAMPLE2,120,6
EXAMPLE3,60,6
EXAMPLE4,30,6
$ cat file_L2.csv
EXAMPLEfoo,60,0
EXAMPLEbar,30,6
EXAMPLE1,60,3
EXAMPLE2,120,0
EXAMPLE3,60,6
EXAMPLE4,30,6
$ cat file_L11.csv
EXAMPLEfoo,60,0
EXAMPLEbar,30,6
EXAMPLE1,60,3
EXAMPLE2,120,0
EXAMPLE3,60,0
EXAMPLE4,30,6
use strict;
use warnings;
use Text::CSV;
my $csv = Text::CSV->new;
sub parse_line {
$csv->parse(shift) or die $!;
return $csv->fields;
}
my @metadata;
my @files = parse_line(scalar <>);
my @header = parse_line(scalar <>); # Ignore.
for my $i (0 .. $#files){
next unless length $files[$i];
open(my $h, '>', "$files[$i].csv") or die $!;
push @metadata, {column => $i, handle => $h};
}
while (my $line = <>){
my @fields = parse_line($line);
for my $m (@metadata){
$csv->print($m->{handle}, [ @fields[0, 1, $m->{column}] ]);
print {$m->{handle}} "\n";
}
}