поиск шаблонов в CSV-файле - PullRequest
0 голосов
/ 10 января 2019

пытается отсортировать CSV-файл на основе повторяющихся строк

awk -F, 'NR>1{arr[$4,",",$5,",",$6,,",",$7,",",$8,",",$9]++}END{for (a in arr) printf "%s\n",  arr[a] "-->" a}' test.txt

Входной файл

a,b,d,1,2,3,4,5,6,y,x,z
k,s,t,1,2,3,4,5,6,t,z,s
a,b,k,1,4,5,5,5,6,k,r,s

Создать файл с

a,b,d,1,2,3,4,5,6,y,x,z-->2
k,s,t,1,2,3,4,5,6,2,t,z,s-->2
a,b,k,1,4,5,5,5,6,1,k,r,s-->1
  • где последний столбец содержит количество вхождений в шаблон чисел, которые начинаются с 4-го места до 9-го.

Подсчитать и отсортировать повторяющиеся строки

Я дошел до того, что у меня есть шаблоны с подсчетом - но я не знаю, как добавить остальные строки в строку:

спасибо за поддержку.

Ответы [ 5 ]

0 голосов
/ 10 января 2019

Поскольку проблема напоминает шаблон SQL, вы также можете использовать sqlite. Проверьте это.

$ cat shimon.txt
a,b,d,1,2,3,4,5,6,y,x,z
k,s,t,1,2,3,4,5,6,t,z,s
a,b,k,1,4,5,5,5,6,k,r,s
$ cat sqllite_cols4_to_9.sh
#!/bin/sh
sqlite3 <<EOF
create table data(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12);
.separator ','
.import "$1" data
select t1.*, " --> " || t2.cw from data t1, ( select c4,c5,c6,c7,c8,c9, count(*) as cw from data group by c4,c5,c6,c7,c8,c9 ) t2
where t1.c4=t2.c4 and t1.c5=t2.c5 and t1.c6=t2.c6 and t1.c7=t2.c7 and t1.c8=t2.c8 and t1.c9=t2.c9;
EOF
$ ./sqllite_cols4_to_9.sh shimon.txt
a,b,d,1,2,3,4,5,6,y,x,z, --> 2
k,s,t,1,2,3,4,5,6,t,z,s, --> 2
a,b,k,1,4,5,5,5,6,k,r,s, --> 1
$
0 голосов
/ 10 января 2019

Ответ Джеймса Брауна - очень простое двухпроходное решение, которое имеет преимущество в том, что вам не нужно хранить файл в памяти, а в том, что вам нужно прочитать файл дважды. Следующее решение будет делать только обратное, читать только файлы, но хранить их в памяти. Для этого нам нужно 3 массива. Массив c для отслеживания количества, массив b в качестве буфера и массив a для отслеживания исходного порядка.

Кроме того, мы будем использовать индексы многомерного массива:

Допустимый индекс массива должен состоять из одного или нескольких -разделенных выражений, аналогично тому, как многомерные массивы индексируются в некоторых языках программирования. Поскольку массивы awk действительно одномерны, такой список, разделенный , должен быть преобразован в одну строку путем объединения строковых значений отдельных выражений, каждое из которых отделяется от другого значением переменной SUBSEP. Таким образом, следующие две операции с индексами должны быть эквивалентны:

var[expr1, expr2, ... exprn]
var[expr1 SUBSEP expr2 SUBSEP... SUBSEP exprn]

Решение теперь гласит:

{ a[NR] = $4 SUBSEP $5 SUBSEP $6 SUBSEP $7 SUBSEP $8 SUBSEP $9
  b[$4,$5,$6,$7,$8,$9] = $0
  c[$4,$5,$6,$7,$8,$9]++ }
END { for(i=1;i<=NR;++i) print b[a[i]],"-->",c[a[i]] }
0 голосов
/ 10 января 2019

Вы также можете попробовать Perl. Файл читается только один раз, поэтому он будет быстрее. Проверьте это:

$ cat shimon.txt
a,b,d,1,2,3,4,5,6,y,x,z
k,s,t,1,2,3,4,5,6,t,z,s
a,b,k,1,4,5,5,5,6,k,r,s
$ perl -F, -lane ' $v=join(",",@F[3..8]);$kv{$_}{$v}=$kv2{$v}++; END { while(($x,$y)=each (%kv)){ while(($p,$q)=each (%{$y})) { print "$x --> $kv2{$p}" }}}' shimon.txt
a,b,k,1,4,5,5,5,6,k,r,s --> 1
a,b,d,1,2,3,4,5,6,y,x,z --> 2
k,s,t,1,2,3,4,5,6,t,z,s --> 2
$

Другой Perl - более короткий код

$ perl -F, -lane ' $kv{$_}=$kv2{join(",",@F[3..8])}++; END { for(keys %kv) { $t=join(",",(split /,/)[3..8]); print "$_ --> $kv2{$t}" } } ' shimon.txt
a,b,k,1,4,5,5,5,6,k,r,s --> 1
a,b,d,1,2,3,4,5,6,y,x,z --> 2
k,s,t,1,2,3,4,5,6,t,z,s --> 2

или

$ perl -F, -lane ' $kv{$_}=$kv2{join(",",@F[3..8])}++; END { for(keys %kv) { print "$_ --> ",$kv2{join(",",(split /,/)[3..8])} } } ' shimon.txt
a,b,k,1,4,5,5,5,6,k,r,s --> 1
a,b,d,1,2,3,4,5,6,y,x,z --> 2
k,s,t,1,2,3,4,5,6,t,z,s --> 2
$
0 голосов
/ 10 января 2019

Не могли бы вы попробовать, читая Input_file только один раз.

awk '
BEGIN{
  FS=OFS=","
}
{
  a[FNR]=$0
  b[FNR]=$4 FS $5 FS $6 FS $7 FS $8 FS $9
  c[$4 FS $5 FS $6 FS $7 FS $8 FS $9]++
}
END{
  for(i=1;i<=FNR;i++){
    print a[i]" ---->" c[b[i]]
  }
}'  Input_file
0 голосов
/ 10 января 2019

Решение, при котором данные читаются дважды, на первом ходу подсчитываются дубликаты, а на втором выводятся:

$ awk -F, '
NR==FNR {
    a[$4 ORS $5 ORS $6 ORS $7 ORS $8 ORS $9]++              # count
    next
}
{
    print $0 "-->" a[$4 ORS $5 ORS $6 ORS $7 ORS $8 ORS $9] # output
}' file file
a,b,d,1,2,3,4,5,6,y,x,z-->2
k,s,t,1,2,3,4,5,6,t,z,s-->2
a,b,k,1,4,5,5,5,6,k,r,s-->1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...