Разделить CSV на несколько файлов, содержащих заданное количество уникальных значений полей
Как начинающий 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,333
а также 444,555,666
соответственно в первом столбце. Любая помощь будет оценена.
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. Затем мы подсчитываем каждое уникальное значение, которое мы получаем из первого столбца, и всякий раз, когда оно становится четвертым, мы сбрасываем наш счетчик и переходим к следующему имени файла.
Вот некоторые примеры данных, которые я использовал, которые только ваши с некоторыми дополнительными строками.
~$ 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
Этот однострочник поможет:
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