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

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



Em Sat, 5 Jul 2008 00:48:03 -0300 (BRT)
linux@juniorpolegato.com.br escreveu:

[...]

> 
> 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

De fato, funciona perfeitamente, para números de 0 a 9.

> 
>     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
> 

Aqui, encontrei o seguinte problema: para um arquivo contendo as linhas
abaixo, funciona perfeitamente.

A       3       3       4       5
B       2       3       4       5
C       4       4       5       6
D       4       5       6       7

Já ao substituir números por letras e removendo o "nome" de cada linha,
temos o seguinte:

$ cat teste.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
C       C       D       E
B       C       D       E
D       D       E       F
D       E       F       G


>     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
> 

Este funcionou perfeitamente se houver somente uma repetição por linha!
em um arquivo como este aí embaixo

C       C       D       D
B       C       D       E
D       D       E       F
D       E       F       G

a resposta é:

C       C       D       D => C => C       C       D       D
B       C       D       E => 
D       D       E       F => D => D       D       E       F
D       E       F       G => 


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

Trata-se de uma coleção de aproximadamente 700 imagens separadas em 47
sub-conjuntos. Serão, em sua maioria, itens catalogados como "K 1314" ou
"F 2241" e é preciso determinar: i) se algum destes itens se repete
dentro de um dos sub-conjuntos; e ii) se se algum destes itens se
repete fora de um dos sub-conjuntos, preciso saber em quais destes
sub-conjuntos isto ocorre.

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

Muito obrigado,

Gunther Furtado


Reply to: