我有一个很大的 csv 文件,如下所示:
1 , aaa, bbb, ...
1 , ccc, ddd, ...
2 , aaa, bbb, ...
..
10 , aaa, bbb, ...
..
1000 , aaa, bbb, ...
我想根据第一列最多为 n 的倍数,将其拆分为单独的 csv 文件,例如。对于 n=10:
0.csv 将包含:
1 , aaa, bbb, ...
1 , ccc, ddd, ...
2 , aaa, bbb, ...
..
10 , aaa, bbb, ...
1.csv 将包含:
11 , ccc, ddd, ...
12 , aaa, bbb, ...
12 , aaa, bbb, ...
..
20 , aaa, bbb, ...
问题是,我事先不知道应该为每个文件分配多少行,并且它并不是像使用 awk 那样简单地将第一列与整数匹配。
我知道这最接近我想要的:
awk -F ',' '!seen[$1]++{f=$1".csv"; print h > f};{f=$1".csv"; print >> f; close(f)}' file.csv
然而,这只按第一列值分割,这会创建太多文件,而我想将它们分组为 n 上的多个文件。
答案1
您需要使用 awk 的模数或%
运算符。
例如
$ awk -F, 'BEGIN { group=0; f="0.csv"};
$1 % 10 == 0 && !seen[$1]++ {group++; f=group".csv"};
{ print >> f}' input.txt
只要$1
能被 10 整除,它就会递增变量group
并更新输出文件名以匹配。
使用以下输入文件:
$ cat input.txt
1 , aaa, bbb, ...
1 , ccc, ddd, ...
2 , aaa, bbb, ...
10 , aaa, bbb, ...
11 , aaa, bbb, ...
12 , aaa, bbb, ...
20 , aaa, bbb, ...
21 , aaa, bbb, ...
22 , aaa, bbb, ...
30 , aaa, bbb, ...
31 , aaa, bbb, ...
32 , aaa, bbb, ...
40 , aaa, bbb, ...
41 , aaa, bbb, ...
42 , aaa, bbb, ...
50 , aaa, bbb, ...
51 , aaa, bbb, ...
52 , aaa, bbb, ...
60 , aaa, bbb, ...
61 , aaa, bbb, ...
62 , aaa, bbb, ...
70 , aaa, bbb, ...
71 , aaa, bbb, ...
72 , aaa, bbb, ...
1000 , aaa, bbb, ...
它产生以下输出文件:
$ head *.csv
==> 0.csv <==
1 , aaa, bbb, ...
1 , ccc, ddd, ...
2 , aaa, bbb, ...
==> 1.csv <==
10 , aaa, bbb, ...
11 , aaa, bbb, ...
12 , aaa, bbb, ...
==> 2.csv <==
20 , aaa, bbb, ...
21 , aaa, bbb, ...
22 , aaa, bbb, ...
==> 3.csv <==
30 , aaa, bbb, ...
31 , aaa, bbb, ...
32 , aaa, bbb, ...
==> 4.csv <==
40 , aaa, bbb, ...
41 , aaa, bbb, ...
42 , aaa, bbb, ...
==> 5.csv <==
50 , aaa, bbb, ...
51 , aaa, bbb, ...
52 , aaa, bbb, ...
==> 6.csv <==
60 , aaa, bbb, ...
61 , aaa, bbb, ...
62 , aaa, bbb, ...
==> 7.csv <==
70 , aaa, bbb, ...
71 , aaa, bbb, ...
72 , aaa, bbb, ...
==> 8.csv <==
1000 , aaa, bbb, ...
简单递增的另一种方法group
是使其等于$1 / 10
。例如
$ awk -F, '{ group = int($1 / 10); f=group".csv" ; print >> f }' input.txt
如果您希望能够n
在命令行上指定而不是对其进行硬编码:
$ awk -F, 'BEGIN { group=0; f="0.csv"};
$1 % n == 0 && !seen[$1]++ {group++; f=group".csv"};
{ print >> f}' n=5 input.txt