Создание нескольких CSV-файлов из данных в файле csv

Системный OSX или Linux

Я пытаюсь автоматизировать мой рабочий процесс на работе, каждую неделю я получаю файл excel, который я конвертирую в csv.

Пример:

,,L1,,,L2,,,L3,,,L4,,,L5,,,L6,,,L7,,,L8,,,L9,,,L10,,,L11, Title,r/t,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,neede d,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst EXAMPLEfoo,60,6,6,6,0,0,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 EXAMPLEbar,30,6,6,12,6,7,14,6,6,12,6,6,12,6,8,16,6,7,14,6,7.5,15,6,6,12,6,8,16,6,0,0,6,7,14 EXAMPLE1,60,3,3,3,3,5,5,3,4,4,3,3,3,3,6,6,3,4,4,3,3,3,3,4,4,3,8,8,3,0,0,3,4,4 EXAMPLE2,120,6,6,3,0,0,0,6,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 EXAMPLE3,60,6,6,6,6,8,8,6,6,6,6,6,6,0,0,0,0,0,0,6,8,8,6,6,6,0,0,0,0,0,0,0,10,10 EXAMPLE4,30,6,6,12,6,7,14,6,6,12,6,6,12,3,5.5,11,6,7.5,15,6,6,12,6,0,0,6,9,18,6,0,0,6,6.5,13 

И так вы можете получить представление о том, как это выглядит в excel: alt text http://i42.tinypic.com/2dt2glt.png

Что мне нужно сделать, это создать несколько файлов csv для каждого экземпляра в строке 1, поэтому L1, L2, L3, L4 …

И в этом каждый файл csv он должен содержать заголовок, r / t, необходимый

Таким образом, для L1 пример out put будет выглядеть так:

 EXAMPLEfoo,60,6 EXAMPLEbar,30,6 EXAMPLE1,60,3 EXAMPLE2,120,6 EXAMPLE3,60,6 EXAMPLE4,30,6 

И для L2:

 EXAMPLEfoo,60,0 EXAMPLEbar,30,6 EXAMPLE1,60,3 EXAMPLE2,120,0 EXAMPLE3,60,6 EXAMPLE4,30,6 

И так далее.

Я пробовал играть с sed и awk и ударил Google, но я не нашел ничего, что действительно решает проблему.

Я бы предположил, что perl будет особенно подходит для этого или, может быть, python, поэтому я был бы более чем счастлив принять предложения от пользователей.

Итак, какие-то предложения?

Заранее спасибо.

6 Solutions collect form web for “Создание нескольких CSV-файлов из данных в файле csv”

Использование только 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 

Как однострочный:

 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 

Пример вывода:

 $ 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 

Perl "однострочный"

 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}' 

Для тех, у кого есть проблемы с чтением:

 $ 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; } 

попробуй это

 #!/bin/bash awk 'BEGIN{ OFS=FS="," } NR==1{ for(i=1;i<=NF;i++){ if($i){ f[i]=$i } } } NR>2{ for(o in f){ print $1,$2, $o > "file_"f[o]".csv" } } ' file 

вывод

 $ 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 
 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"; } } 

Взгляните на модуль perl Text :: CSV_XS – подпрограммы обработки значений, разделенных запятыми. Я нашел этот модуль очень полезным при работе с файлами CSV.

В Python, немного взломанный и непроверенный, но должен делать работу:

 import csv r = csv.reader(open(r'file.csv'), dialect='excel') topline = r.next() headerline = r.next() lastcell = '' for i, cell in enumerate(topline): #Copy cells forwards in the top line, so L1 for example goes across all cells if cell == '': topline[i] = lastcell else: lastcell = cell for i in range(len(headerline)): #Copy the topline cells into the header line, so the headerline cells should be unique headerline[i] = '-'.join((topline[i], headerline[i])) rows = [dict(zip(headerline, line)) for line in r] # Rows should now consist of dicts of the form {'Title': 'EXAMPLEfoo', 'r/t': '60', 'L1-needed': '6' ...} for lval in frozenset(topline): #Use frozenset to ensure we only have unique values. if lval != '': #Make sure we don't look at the blank value w = csv.writer(open(r'%s.csv' % lval, 'w'), dialect='excel') for row in rows: line = [row['Title'], row['r/t'], row['-'.join((lval, 'needed'))]] w.writerow(line) 
  • разбивать большую текстовую (xyz) базу данных на x равных частей
  • Регулярное выражение - заменить все пробелы в начале строки на периоды
  • Удаление дубликатов PCR из файла Fastq, содержащего уникальные молекулярные идентификаторы
  • Как получить плоский XML, чтобы внешние объекты были объединены на верхний уровень
  • Python - используя подпроцесс для вызова sed?
  • разбиение файла на более мелкие файлы с использованием количества полей
  • Отменить токенину новой строки в одном токене на строки файлов? - Unix
  • извлекать каждый файл последовательности в виде отдельного файла
  • Python - лучший язык программирования в мире.