[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [assunto paralelo] imprimir linhas que contenham valores repetidos



> Opa.. cheguei agora aqui..
> > hehehe eh facinho brother..
> vamos la..
> > Depende da faixa de valores que vc tem dentro do arquivo.. mas vou dar
> exemplo do que criei aqui..
> > [rodrigo@core:/home/rodrigo]$ cat num
> A   3   3   4   5
> B   2   3   4   5
> C   4   4   5   6
> D   4   5   6   4
> E   2   3   3   2
> F   1   3   2   5
> G   9   1   7   9
> #!/bin/sh
> # rescobarrj@gmail.com
> arquivo="num"           # NOME DO ARQUIVO
> tamanho_final="9"    # VALOR MAXIMO DENTRO DO ARQUIVO
> for ((tamanho_inicial = 1; tamanho_inicial < $[tamanho_final + 1];
> tamanho_inicial++))
>  do
>   cat num |awk '/'$tamanho_inicial'.*'$tamanho_inicial'/' >> resultado
>  done
> cat resultado |sort|uniq
> Que finalmente gera..
> [rodrigo@core:/home/rodrigo]$ sh s.sh
> A   3   3   4   5
> C   4   4   5   6
> D   4   5   6   4
> E   2   3   3   2
> G   9   1   7   9
> Mas tem um problema aqui.. por exemplo.. se voce tiver valores maiores que
> 10 já nao vai dar para comparar, porque ele esta comparando caracter por
> caracter.. ou seja.. voce teria
> X   1   3   5   15
> Ele acharia que eh igual porque ele irá procurar caracter a caracter e nao
> cadeia de caracteres..
> Posta ai pra gente se vc tem numeros maiores que 9 que tentaremos achar
> uma outra solucao..

Olá,

    Com número até 9 (uma linha só):

$ egrep '(0.*0|1.*1|2.*2|3.*3|4.*4|5.*5|6.*6|7.*7|8.*8|9.*9)' arquivo.txt

    Seguindo a mesma idéia, com números maiores até 99, deve-se envolver
os números até 9 por \<n\>, por exemplo até 15 (uma linha só):

$ egrep
'(\<0\>.*\<0\>|\<1\>.*\<1\>|\<2\>.*\<2\>|\<3\>.*\<3\>|\<4\>.*\<4\>|\<5\>.*\<5\>|\<6\>.*\<6\>|\<7\>.*\<7\>|\<8\>.*\<8\>|\<9\>.*\<9\>|10.*10|11.*11|12.*12|13.*13|14.*14|15.*15)'
arquivo.txt

    Claro que fazer na mão dá trampo, então para gerar a seqüência com
todos envolvidos, pode-se usar (uma linha só):

for i in `seq 0 n`; do echo -n "\<$i\>.*\<$i\>|"; done; echo

    Agora pode-se ainda abstrair e não colocar apenas números, pode ser
letras também no lugar dos números na expressão regular do egrep.

    Indo um pouco mais além, pode-se ainda criar um "while read linha"
para pegar cada linha, decompor esta em colunas, pegar uma coluna e
comparar com as demais, podendo a primeira coluna ser ignorada (uma
linha só):

cat arquivo.txt | while read linha; do coluna=($linha);
colunas=${#coluna[@]}; for ((i=1; i<colunas-1; i++)); do for ((j=i+1;
j<colunas; j++)); do if ((coluna[i]==coluna[j])); then echo "$linha";
i=colunas; break; fi; done; done; done

    Porém aqui tem uma ressalva devido a caracteres reservados do bash que
podem estar na linha, o que pode/vai causar erros. Isso também poderia
ser feito usando a comparação por "expr":

cat arquivo.txt | while read linha; do echo -n "$linha => "; for coluna in
$linha; do if expr "$linha" : ".*\<$coluna\>.*\<$coluna\>.*" > /dev/null;
then echo -n "$coluna => $linha"; break; fi; done; echo; done

    Se ainda assim tiver problemas, relate melhor os problemas que
proporemos uma ajuda para encontrar a melhor solução.

PS: '\<...\>' é uma boa alternativa quando se trabalha com valores
separados por caracteres não visíveis.


[]'s
        Junior Polegato


Reply to: