classifica CSV por número de colunas em linhas?

1

Eu tenho vários arquivos CSV com muitos registros. O número total de linhas deve ser 134. Tenho muitos arquivos e cada linha tem seu próprio número de colunas (de 15 a 200). Eu preciso classificá-los de acordo com o número de colunas deles.

Consegui contar as colunas de um arquivo usando:

$ awk -F"," '{print NF}' file # 1.csv

... o que dá algo como:

134
134
134
5
25
133
...

Agora, gostaria de adicionar esses números a cada linha, para que eu possa classificar minhas linhas posteriormente de acordo com ela. Como posso adicionar essa informação no início de cada uma e classificar?

Eu também gostaria de dividir os arquivos com valor = 134 em um arquivo outro por sua respectiva contagem.

exemplo de arquivo INPUT pequeno (são 3 linhas):

2,"A.B.C.D",50,"SDf3oa701-ab73-a0pcs90","7012218969217-1413752517-32448","SDf3oa701-ab73-a0pcs90","SIP",,"<[email protected]>;tag=70122","<[email protected]>",17,0,"00:01:57.827 GMT Oct 20 2014","00:00:00.000 UTC Jan 01 1970","00:01:57.870 GMT Oct 20 2014",3,"sp3",1904,"sp3",1904,"realm_IN","realmTERM_OUT",,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,"Sw-buildabcd","GMT-03:00",0,"[email protected]",,,,,,"X.Y.Z.W:50","A.S.D.F:50","A.S.D.F:50","A.S.D.F:50",,1,2,1,404,"[email protected]",,,4493101
2,"A.B.C.D",50,,,,4493105
2,"A.B.C.D",50,,"[email protected]",,,4493106
    
por Hussein Kray 25.11.2014 / 12:06

3 respostas

2

Pense que isso é o que você quer
Adicione -F, para separados por vírgulas.
Por exemplo, awk -F, '$(NF+1)=NF' file

Adicionar número ao final das linhas

 awk '$(NF+1)=NF' file

Entrada

1
1 2 3
1 2
1 2 3 4 5 6
a b

Saída

1 1
1 2 3 3
1 2 2
1 2 3 4 5 6 6
a b 2

Classificar linhas

 awk '{a[NF]=a[NF]?a[NF]"\n"$0:$0;x=x<NF?NF:x}END{for(i=1;i<=x;i++)if(i in a)print a[i]}'

Entrada

1
1 2 3
1 2
1 2 3 4 5 6
a b

Saída

1
1 2
a b
1 2 3
1 2 3 4 5 6

Imprimir para arquivos diferentes

Usando tamanho de campo de 4 por exemplo, mude para 134 ou o que você quiser para o seu

 awk '{print > (NF>=4?"LargeFile.txt":"SmallFile.txt")}' file 

Entrada

1
1 2 3
1 2
1 2 3 4 5 6
a b

Saída

LargeFile.txt

 1 2 3 4 5 6

SmallFile.txt

1
1 2 3
1 2
a b
    
por 25.11.2014 / 12:15
2

Semelhante à resposta de @ terdon, mas com sed :

{ seq -s, 10; seq -s, 5; seq -s, 15; } | 
tee - -

Esse é o meu infil - parece:

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

Eu posso então fazer:

sed 'h;s/[^,]*//g;G;s/\n/ /' | sort -t\  -nk1,1

... que fica ...

,,,, 1,2,3,4,5
,,,, 1,2,3,4,5
,,,, 1,2,3,4,5
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

Os números não estão lá, mas a contagem é bastante certa, eu acho. Para remover as vírgulas principais que posso fazer:

PIPELINE | sed 's/,* //'

... que fica ...

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

Talvez não seja a resposta mais auspiciosa até agora, mas a principal razão pela qual decidi escrever isso foi que você mencionou que deseja escrever linhas com 134 entradas separadas por vírgula em outro arquivo. Isso, por acaso, é uma questão simples com sed . Por exemplo - digamos que eu queria escrever as linhas com 10 campos da seqüência acima para um file2 :

PIPELINE | sed '/^\([^,]*,[^,]*\)\{9\}$/w file2'
cat file2

OUTPUT

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10

Eu uso \{9\} acima porque ele especifica 9 instâncias do padrão - o que torna 9 delimitadores em 10 campos delimitados. Os intervalos são simplesmente manipulados também:

PIPELINE | sed '/^\([^,]*,[^,]*\)\{4,9\}$/w file2'
cat file2

OUTPUT

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
    
por 25.11.2014 / 15:49
1

Isso adicionará o número de campos (separados por vírgulas) ao início de cada linha, imprimirá a linha e classificará tudo:

awk -F"," '{print NF,$0}' *csv | sort -nk1,1

O -n é de classificação numérica e o -k1,1 garante que seja classificado apenas no primeiro campo. Para remover o número de campos após a classificação, use:

awk -F"," 'print NF,$0' *csv | sort -nk1,1 | cut -d ' ' -f 2- 

OBSERVAÇÃO : isso será interrompido com muita facilidade, dependendo dos dados reais. Você pode ter vírgulas dentro de campos? Você pode ter campos abrangendo várias linhas? Esta é uma abordagem muito ingênua e não pode lidar com nada disso.

    
por 25.11.2014 / 12:33