我很难将一个大的(50GB)csv文件分解成小部分。 每行有几千个字段。 一些字段是双引号的string,其他的是整数,小数和布尔值。
我想逐行parsing文件,并按每行的字段数分割。 这些string可能包含几个逗号(如),以及一些空字段。
,, 1,30,50,“父子,女儿卖4000元”,,,,, 12 ,,, 20.9,0,
我试过使用
perl -pe' s{("[^"]+")}{($x=$1)=~tr/,/|/;$x}ge ' file >> file2
将引号内的逗号改为| 但是这并没有奏效。 我打算使用
awk -F"|" conditional statement appending to new k_fld_files file2
请问有更简单的方法吗? 我在看Python,但我可能需要一个实用程序,将stream处理文件,逐行。
使用Python – 如果你只是想解析CSV,包括嵌入的分隔符,并流出一个新的分隔符,然后如:
import csv import sys with open('filename.csv') as fin: csvout = csv.writer(sys.stdout, delimiter='|') for row in csv.reader(fin): csvout.writerow(row)
否则,做这些事情并不难多少。
输出到每列文件的示例(未经测试):
cols_to_output = {} for row in csv.reader(fin): for colno, col in enumerate(row): output_to = cols_to_output.setdefault(colno, open('column_output.{}'.format(colno), 'wb') csv.writer(output_to).writerow(row) for fileno in cols_to_output.itervalues(): fileno.close()
这是一个awk
选择。
假设引用的字符串格式良好,即始终有起始和终止引号,并且在其他引号内没有引号,则可以通过在每个其他字段上执行gsub
来替代您所建议的替换|
。
用管道
下面是一个例子,说明如何在使用coreutils
cut
3列到第6列,第11列和第14-15列的时候这样做:
awk -F'"' -v OFS='' ' NF > 1 { for(i=2; i<=NF; i+=2) { gsub(",", "|", $i); $i = FS $i FS; # reinsert the quotes } print }'\ | cut -d , -f 3-6,11,14-15 \ | awk -F'"' -v OFS='' -e ' NF > 1 { for(i=2; i<=NF; i+=2) { gsub("\\|", ",", $i) $i = FS $i FS; # reinsert the quotes } print }'
请注意,还有一个额外的后处理步骤可以恢复|
到,
。
完全在awk中
或者,你可以在awk
完成整个事情,但是在范围规范方面有一些缺失。 这里我们只抓取第3列到第6列:
extract.awk
BEGIN { OFS = "" start = 3 end = 6 } { for(i=2; i<=NF; i+=2) { gsub(",", "|", $i) $i = FS $i FS } split($0, record, ",") for(i=start; i<=end-1; i++) { gsub("\\|", ",", record[i]) printf("%s,", record[i]) } gsub("\\|", ",", record[end]) printf("%s\n", record[end]) }