2

の初心者として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

それぞれに3 つの(この場合) 一意の値が含まれ111,222,333444,555,666それぞれが最初の列に含まれます。どんな助けでも大歓迎です。

4

2 に答える 2

2

これでうまくいきます。かなり読みやすく、理解しやすいと思います。

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
于 2015-03-25T17:29:14.227 に答える
1

このワンライナーが役立ちます:

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
于 2015-03-25T17:18:56.533 に答える