如何在UNIX环境下使用split命令动态拆分大csv文件为125mb ~ 1000mb的小csv文件


  • 我正试图将大型csv文件拆分为小型csv文件从125MB到1GB。分割命令将工作,如果我们给number每个文件的记录将被分割,但我想要得到行数动态根据文件大小。如果文件大小为20GB,则使用复制命令将整个文件加载到红移表中但是这会花费很多时间,所以如果我们把20GB的文件分成这样我就能得到很好的结果。

  • 示例20GB的文件,我们可以拆分6_000_000条记录每个文件,这样块文件大小大约125mb,这样我想要600_000行数动态依赖于大小

您可以获得以MB为单位的文件大小,然后除以您需要预先确定的理想大小(对于我的示例,我选择了最小的125MB),这将给出块的数量。

然后获得行数(wc -l,假设您的CSV在单元格内没有换行),并将其除以块数,得到每个块的行数。

每块行数是你的"每块行数"。最后可以传递给split的数

因为我们做的是除法,很可能会得到一个余数,所以您可能会得到一个额外的文件,其中包含相对较少的余数行(您可以在示例中看到)。

我是这样编写的。我使用shell检查,所以我认为这是相当POSIX兼容的:

csvFile=$1
maxSizeMB=125
rm -f chunked_*
fSizeMB=$(du -ms "$csvFile" | cut -f1)
echo "File size is $fSizeMB, max size per new file is $maxSizeMB"
nChunks=$(( fSizeMB / maxSizeMB ))
echo "Want $nChunks chunks"
nRows=$(wc -l "$csvFile" | cut -d' ' -f2)
echo "File row count is $nRows"
nRowsPerChunk=$(( nRows / nChunks ))
echo "Need $nChunks files at around $nRowsPerChunk rows per file (plus one more file, maybe, for remainder)"

split -d -a 4 -l $nRowsPerChunk "$csvFile" "chunked_"

echo "Row (line) counts per file:"
wc -l chunked_00*
echo
echo "Size (MB) per file:"
du -ms chunked_00*

我创建了一个模拟CSV,有60_000_000行,大约5GB:

ll -h gen_60000000x11.csv
-rw-r--r--  1 zyoung  staff   4.7G Jun 24 15:21 gen_60000000x11.csv

当我运行这个脚本时,我得到了这样的输出:

./main.sh gen_60000000x11.csv
File size is 4801MB, max size per new file is 125MB
Want 38 chunks
File row count is 60000000
Need 38 files at around 1578947 rows per file (plus one more file, maybe, for remainder)
Row (line) counts per file:
1578947 chunked_0000
1578947 chunked_0001
1578947 chunked_0002
...
1578947 chunked_0036
1578947 chunked_0037
14 chunked_0038
60000000 total
Size (MB) per file:
129     chunked_0000
129     chunked_0001
129     chunked_0002
...
129     chunked_0036
129     chunked_0037
1       chunked_0038

最新更新