将 CSV 拆分为包含一组唯一字段值的多个文件
Split CSV to Multiple Files Containing a Set Number of Unique Field Values
作为 awk
的初学者,我能够通过
拆分具有唯一值的数据
awk -F, '{print >> ".csv";close()}' myfile.csv
但我想根据附加条件拆分大型 CSV 文件,该附加条件是在特定列中出现唯一值。
具体来说,输入
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
我希望输出文件是
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
和
444,1,1,1
444,1,0,1
555,1,1,1
666,1,0,0
其中每个包含 三个(在本例中)唯一值,分别在第一列中 111,222,333
和 444,555,666
。
任何帮助将不胜感激。
这条线会有所帮助:
awk -F, -v u=3 -v i=1 '{a[];
if (length(a)>u){close(i".csv");++i;delete a;a[]}print>i".csv"}' file
您将 u=3
值更改为 x
以获得每个文件的 x
个唯一值。
如果你 运行 这行输入文件,你应该得到 1.csv and 2.csv
编辑(添加一些测试输出):
kent$ ll
total 4.0K
drwxr-xr-x 2 kent kent 60 Mar 25 18:19 ./
drwxrwxrwt 19 root root 580 Mar 25 18:18 ../
-rw-r--r-- 1 kent kent 90 Mar 25 17:57 f
kent$ cat f
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
kent$ awk -F, -v u=3 -v i=1 '{fn=i".csv";a[];if (length(a)>u){close(fn);++i;delete a;a[]}print>fn}' f
kent$ head *.csv
==> 1.csv <==
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
==> 2.csv <==
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
这样就可以了,我发现它非常易读且易于理解:
awk -F',' 'BEGIN { count=0; filename=1 }
x[]++==0 {count++}
count==4 { count=1; filename++}
{print >> filename".csv"; close(filename".csv");}' file
我们从计数 0 开始,文件名从 1 开始。然后我们计算从第一列获得的每个唯一值,每当它是第 4 个时,我们重置计数并移动到下一个文件名。
这是我使用的一些示例数据,只是你的一些额外的行。
~$ cat test.txt
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
777,1,1,1
777,1,0,1
777,1,1,0
777,1,1,1
888,1,0,1
888,1,1,1
999,1,1,1
999,0,0,0
999,0,0,1
101,0,0,0
102,0,0,0
而 运行 awk 是这样的:
~$ awk -F',' 'BEGIN { count=0; filename=1 }
x[]++==0 {count++}
count==4 { count=1; filename++}
{print >> filename".csv"; close(filename".csv");}' test.txt
我们看到以下输出文件和内容:
~$ cat 1.csv
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
~$ cat 2.csv
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
~$ cat 3.csv
777,1,1,1
777,1,0,1
777,1,1,0
777,1,1,1
888,1,0,1
888,1,1,1
999,1,1,1
999,0,0,0
999,0,0,1
~$ cat 4.csv
101,0,0,0
102,0,0,0
作为 awk
的初学者,我能够通过
awk -F, '{print >> ".csv";close()}' myfile.csv
但我想根据附加条件拆分大型 CSV 文件,该附加条件是在特定列中出现唯一值。
具体来说,输入
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
我希望输出文件是
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
和
444,1,1,1
444,1,0,1
555,1,1,1
666,1,0,0
其中每个包含 三个(在本例中)唯一值,分别在第一列中 111,222,333
和 444,555,666
。
任何帮助将不胜感激。
这条线会有所帮助:
awk -F, -v u=3 -v i=1 '{a[];
if (length(a)>u){close(i".csv");++i;delete a;a[]}print>i".csv"}' file
您将 u=3
值更改为 x
以获得每个文件的 x
个唯一值。
如果你 运行 这行输入文件,你应该得到 1.csv and 2.csv
编辑(添加一些测试输出):
kent$ ll
total 4.0K
drwxr-xr-x 2 kent kent 60 Mar 25 18:19 ./
drwxrwxrwt 19 root root 580 Mar 25 18:18 ../
-rw-r--r-- 1 kent kent 90 Mar 25 17:57 f
kent$ cat f
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
kent$ awk -F, -v u=3 -v i=1 '{fn=i".csv";a[];if (length(a)>u){close(fn);++i;delete a;a[]}print>fn}' f
kent$ head *.csv
==> 1.csv <==
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
==> 2.csv <==
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
这样就可以了,我发现它非常易读且易于理解:
awk -F',' 'BEGIN { count=0; filename=1 }
x[]++==0 {count++}
count==4 { count=1; filename++}
{print >> filename".csv"; close(filename".csv");}' file
我们从计数 0 开始,文件名从 1 开始。然后我们计算从第一列获得的每个唯一值,每当它是第 4 个时,我们重置计数并移动到下一个文件名。
这是我使用的一些示例数据,只是你的一些额外的行。
~$ cat test.txt
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
777,1,1,1
777,1,0,1
777,1,1,0
777,1,1,1
888,1,0,1
888,1,1,1
999,1,1,1
999,0,0,0
999,0,0,1
101,0,0,0
102,0,0,0
而 运行 awk 是这样的:
~$ awk -F',' 'BEGIN { count=0; filename=1 }
x[]++==0 {count++}
count==4 { count=1; filename++}
{print >> filename".csv"; close(filename".csv");}' test.txt
我们看到以下输出文件和内容:
~$ cat 1.csv
111,1,0,1
111,1,1,1
222,1,1,1
333,1,0,0
333,1,1,1
~$ cat 2.csv
444,1,1,1
444,0,0,0
555,1,1,1
666,1,0,0
~$ cat 3.csv
777,1,1,1
777,1,0,1
777,1,1,0
777,1,1,1
888,1,0,1
888,1,1,1
999,1,1,1
999,0,0,0
999,0,0,1
~$ cat 4.csv
101,0,0,0
102,0,0,0