bash - 在 bash 脚本中将 CSV 文件不均匀地拆分为多个文件
问题描述
我有一个包含几个大 csv 文件的文件夹,我希望拥有可变数量的几乎相同大小的 CSV 文件。
目前,这是我的平均规模的部门实施:
#!/bin/bash
#copy header to all resulting files parts
head -n 1 $1_2021.csv | awk -v NPROC=$(nproc) '{ for (i = 0; i < NPROC; ++i) print $0 > "file_"i".csv" }'
#copy the data but the header for each file part
tail --silent -n+2 $1* | awk -v NPROC=$(nproc) '{ part = NR % NPROC; print $0 >> "file_"part".csv" }'
where$1
是文件的版本,作为参数传递给 bash 脚本,例如v1
或v2
. 输出文件名不相关,目前file_"i".csv
&file_"part".csv
产生相同的文件名,其中part
&i
位于此范围内:(0, NPROC)
文件的一些示例v1_2020.csv
(分号分隔)
DATE;COLOUR;CLOSING;CHANGE;Y
2020-01-02;r;n;4;119
2020-01-02;y;n;56;130
2020-01-03;y;n;3;153
2020-01-03;r;n;46;192
2020-01-03;b;n;20;241
2020-01-04;w;n;1252;252
2020-01-05;w;n;453;253
2020-01-06;b;y;1;279
2020-01-06;b;n;945;294
逐表看起来像这样:
日期 | 颜色 | 关闭 | 改变 |
---|---|---|---|
2020-01-02 | r | n | 4 |
2020-01-02 | 是的 | n | 56 |
2020-01-03 | 是的 | n | 3 |
2020-01-03 | r | n | 46 |
2020-01-03 | b | n | 20 |
2020-01-03 | w | n | 1252 |
2020-01-05 | w | n | 453 |
2020-01-06 | b | 是的 | 1 |
2020-01-06 | b | n | 945 |
我想改进这种划分,使其不会在相同的日期分成不同的文件。所以它应该考虑到DATE
CSV 文件中的列。
电流输出NPROC=2
:
file_1.csv
DATE;COLOUR;CLOSING;CHANGE;Y
2020-01-02;r;n;4;119
2020-01-03;y;n;3;153
2020-01-03;b;n;20;241
2020-01-05;w;n;453;253
2020-01-06;b;n;945;294
file_2.csv
DATE;COLOUR;CLOSING;CHANGE;Y
2020-01-02;y;n;56;130
2020-01-03;r;n;46;192
2020-01-04;w;n;1252;252
2020-01-06;b;y;1;279
新输出NPROC=2
:
无论哪种类型的不均匀拆分为NPROC
多个文件,都不会将日期混淆到不同的文件中。一个日期应该只放在一个文件中,但一个文件应该包含多个日期。
例如,NPROC
如果符合上述条件,任何其他类型的文件拆分都可以:
file_1.csv
DATE;COLOUR;CLOSING;CHANGE;Y
2020-01-02;r;n;4;119
2020-01-02;y;n;56;130
2020-01-03;y;n;3;153
2020-01-03;r;n;46;192
2020-01-03;b;n;20;241
file_2.csv
DATE;COLOUR;CLOSING;CHANGE;Y
2020-01-04;w;n;1252;252
2020-01-05;w;n;453;253
2020-01-06;b;y;1;279
2020-01-06;b;n;945;294
你能给我任何关于不使用 Python 而只是使用 bash 脚本的可能解决方案的提示吗?
解决方案
如果您只想拆分 csv 并为每个拆分添加标题,您可以执行以下操作:
awk -v cnt=6 -F ';' 'FNR==1{header=$0; fn=1}
!(FNR%cnt){
fn++
print header >"file_" fn ".csv"
}
{print $0>"file_" fn ".csv"}' file
如果要根据日期列进行上下文拆分(假设已经排序):
awk -v sp=6 -v fn=1 -F ';' 'FNR==1{header=$0}
cnt++>sp && l1!=$1 {
fn++
cnt=0
print header >"file_" fn ".csv"
}
{print $0>"file_" fn ".csv"; l1=$1}' file
这里的第二个结果:
cat *.csv
DATE;COLOUR;CLOSING;CHANGE
2020-01-02;r;n;4
2020-01-02;y;n;56
2020-01-03;y;n;3
2020-01-03;r;n;46
2020-01-03;b;n;20
2020-01-03;w;n;1252
DATE;COLOUR;CLOSING;CHANGE
2020-01-05;w;n;453
2020-01-06;b;y;1
2020-01-06;b;n;945
推荐阅读
- java - Spring Boot和MyBatis项目中配置多个数据源时发生BindingException
- ibm-integration-bus - IIB 9 为产品进料流占用大量内存
- angular - Angular Reactive 表单默认输入值
- angular - Angular 6 和 Karma 的随机测试失败
- ocaml - 在 OCaml 顶层动态加载 ml 文件?
- monaco-editor - 如何在 monaco-editor 中设置行尾
- networking - SNMP 是否有基于版本的最小超时
- xamarin.android - iCloudStorage.GetChildren() 永远不会返回
- python - 确定 k 均值聚类的准确性
- openssl - SSL_write写入部分数据时如何处理应用程序