将CSV文件拆分为较小的文件,但保留标题吗?

时间:2018-07-19 11:00:32

标签: bash csv awk

我有一个巨大的CSV文件,行数为1m。我想知道是否有办法将此文件拆分为较小的文件,但在所有文件上保留第一行(CSV标头)。

看来split很快,但也很有限。您不能将后缀添加到.csv之类的文件名中。

split -l11000 products.csv file_

有没有一种有效的方法可以仅通过bash来完成此任务?单行命令会很棒。

2 个答案:

答案 0 :(得分:17)

这个问题的答案是 ,这在AWK中是可能的。

这个想法是要牢记标题,并以filename.00001.csv形式的文件名打印其余所有内容:

awk -v l=11000 '(NR==1){header=$0;next}
                (NR%l==2) { 
                   c=sprintf("%0.5d",c+1); 
                   close(file); file=FILENAME; sub(/csv$/,c".csv",file)
                   print header > file
                }
                {print $0 > file}' file.csv

这可以通过以下方式进行:

  • (NR==1){header=$0;next}:如果记录/行是第一行,则将该行另存为 header
  • (NR%l==2){...} :每次我们写入l=11000条记录/行时,我们都需要开始写入新文件。每当记录/行号的模数达到2时,就会发生这种情况。这是在 2,2 + l,2 + 2l,2 + 3l ,....行上发现我们做到了:
    • c=sprintf("%0.5d",c+1) :将计数器加1,然后将其打印为000xx
    • close(file):也关闭刚刚写入的文件。
    • file=FILENAME; sub(/csv$/,c".csv",file)定义新文件名
    • print header > file:打开文件,并将标头写入该文件。
  • {print $0 > file} :将条目写入文件。

答案 1 :(得分:0)

使用GNU split拆分file.csv

export inputPrefix='file' parts=16 && split --verbose -d -n l/${parts} --additional-suffix=.csv --filter='([ "$FILE" != "${inputPrefix}.00.csv" ] && head -1 "${inputPrefix}.csv" ; cat) > "$FILE"' "${inputPrefix}.csv" "${inputPrefix}."