【问题标题】:Split CSV to Multiple Files Containing a Set Number of Unique Field Values将 CSV 拆分为包含一组唯一字段值的多个文件
【发布时间】:2015-05-29 10:54:19
【问题描述】:

作为awk 的初学者,我可以将具有唯一值的数据拆分为

awk -F, '{print >> $1".csv";close($1)}' 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,333444,555,666,分别位于第一列。 任何帮助将不胜感激。

【问题讨论】:

  • 分割文件的条件是什么不清楚。
  • 你的意思是每个文件有 3 个 uniq 值吗?
  • 是的,我刚刚编辑了帖子。

标签: csv awk split conditional-statements find-occurrences


【解决方案1】:

这样就可以解决问题,而且我觉得它可读性强且易于理解:

awk -F',' 'BEGIN { count=0; filename=1 }
            x[$1]++==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[$1]++==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

【讨论】:

  • 如你所说,代码我一看就懂了,谢谢!
【解决方案2】:

这条单线会有所帮助:

awk -F, -v u=3 -v i=1 '{a[$1];
   if (length(a)>u){close(i".csv");++i;delete a;a[$1]}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[$1];if (length(a)>u){close(fn);++i;delete a;a[$1]}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

【讨论】:

    猜你喜欢
    • 2016-07-26
    • 1970-01-01
    • 2017-10-10
    • 2021-06-05
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多