我必须处理来自类似这种格式的大型 CSV 文件的数据。该文件是非常非常大(~200MB),我的电脑处理起来有些困难,所以我想将文件拆分成更小的文件,这样更容易处理。假设文件格式如下:
NAME,SURNAME,SEX,CITY,AGE RANK
Tom,Brown,M,New York,20-40
Dick,Clarke,M,Seattle,0-20
Katie,Johnson,F,Boston,40-60
Harry,Smith,M,Washington,40-60
Amy,Davies,F,Chicago,20-40
Emily,Adams,F,New York,20-40
...
我想将其拆分如下:
- 分开年龄组别
- 每个文件的长度不超过给定的行号,否则再次分割
例如:
- 0-20.1.csv(5000行)
- 0-20.2.csv(5000行)
- 0-20.3.csv(剩余1234行)
- 20-30.1.csv(5000行)
- 20-30.2.csv(剩余4321行)
- ...
我还想在每个输出文件的开头重复输入文件的第一行(标题),并删除一些我不需要的列,但这不是必需的。所以我对年龄等级 20-40 的理想输出将是(假设我想删除一NAME
列AGE RANK
):
SURNAME,SEX,CITY
Brown,M,New York
Davies,F,Chicago
Adams,F,New York
...
有没有办法自动操作这样的文件?我可以使用任何工具或脚本,但我会很多避免使用专有软件。
答案1
如果您提供一个包含足够数据的小示例来拆分,例如 5 行而不是 5000 行,那将会很有帮助。但是,您应该能够在 Awk 中使用类似这样的内容:
awk -F, -v nsplit=5000 '
NR==1 {OFS=FS; hdr=$0; next}
(++count[$5] % nsplit == 1) {
close(fname[$5]);
fname[$5] = $5 "." (++ind[$5]) ".csv";
print hdr > fname[$5]
}
{print > fname[$5]}
' file.csv
测试方式nsplit=2
:
$ awk -F, -v nsplit=2 '
NR==1 {OFS=FS; hdr=$0; next}
(++count[$5] % nsplit == 1) {
close(fname[$5]);
fname[$5] = $5 "." (++ind[$5]) ".csv";
print hdr > fname[$5]
}
{print > fname[$5]}
' file.csv
给出
$ head 0-20.?.csv 20-40.?.csv 40-60.?.csv
==> 0-20.1.csv <==
NAME,SURNAME,SEX,CITY,AGE RANK
Dick,Clarke,M,Seattle,0-20
==> 20-40.1.csv <==
NAME,SURNAME,SEX,CITY,AGE RANK
Tom,Brown,M,New York,20-40
Amy,Davies,F,Chicago,20-40
==> 20-40.2.csv <==
NAME,SURNAME,SEX,CITY,AGE RANK
Emily,Adams,F,New York,20-40
==> 40-60.1.csv <==
NAME,SURNAME,SEX,CITY,AGE RANK
Katie,Johnson,F,Boston,40-60
Harry,Smith,M,Washington,40-60