我有一个文件夹,里面有几个大的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" }'
其中$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 | y | n | >56 |
2020-01-03 | y | n3 | |
2020-01-03 | r | n46 | |
2020-01-03 | b | n | <20>|
2020-01-03 | w | n<1252>||
2020-01-05 | w | n453 | |
2020-01-06 | b | y | <1>|
2020-01-06 | b | n | 945 |
如果您只想拆分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
awk -F';' -v NPROC=2 '
NR == 1 {head = $0; next}
!($1 in dates) {
n = (n + 1) % NPROC
file = "out_" n ".csv"
if (!(file in created)) {
print head > file
created[file]
}
dates[$1] = file
}
{ print > dates[$1] }
' v1_2020.csv
由于NPROC=2,将创建两个输出文件:
$ cat out_0.csv
DATE;COLOUR;CLOSING;CHANGE;Y
2020-01-03;y;n;3;153
2020-01-03;r;n;46;192
2020-01-03;b;n;20;241
2020-01-05;w;n;453;253
$ cat out_1.csv
DATE;COLOUR;CLOSING;CHANGE;Y
2020-01-02;r;n;4;119
2020-01-02;y;n;56;130
2020-01-04;w;n;1252;252
2020-01-06;b;y;1;279
2020-01-06;b;n;945;294
首先,使用命令行工具处理CSV/TSV文件可能很棘手。awk
命令是这里的目标,但它没有内置的对引用的支持;如果您有一个类似column 1; "column 2 has a ';' in it";column 3
的行,那么awk -F';'
将把它看作$1="column 1"
、$2=""column to has a '"
、$3="'in it""
、$4="column3"
。
如果您的数据中没有类似的内容,那么它非常简单。首先,您想将每个日期写入自己的文件:
awk -F';' '{print >>$1".csv"}'
这将使您获得以日期命名的文件,如2020-01-02.csv
。
现在,您可以将这些数据合并到NPROC文件中,只要您只合并整个文件,就不会将给定日期的数据拆分到多个文件中。这里有一种简单(不一定优雅!(的方法:
declare -i lines=$(cat *-*-*.csv | wc -l) chunk cur
(( chunk = lines / NPROC, cur = 1 ))
for f in *-*-*.csv; do
cat "$f" >>"file_$cur.csv"
if (( $(wc -l <"file_$cur.csv") >= chunk )); then
(( cur += 1 ))
fi
done