quinta-feira, 26 de julho de 2007

Resolvendo Problemas Comuns 7 - open failed: |

Imagine um arquivo com algumas linhas duplicadas:

$ cat arquivo
permission denied
bad interpreter
missing separator
set correct localle
parameter list too long
unary operator expected
parameter list too long
bad interpreter


Obter as linhas distintas pode ser feito com a ajuda do sort + uniq

$ cat arquivo | sort | uniq
bad interpreter
missing separator
parameter list too long
permission denied
set correct localle
unary operator expected


- Puxa! Que ótima combinação! Vamos guarda-la?

Bom, podemos querer guardar este e outros comandos em uma variável de ambiente também, afinal, deve funcionar sem maiores problemas, certo?
$ CMD="sort | uniq"
$ cat arquivo | $CMD
sort: open failed: |: No such file or directory


- OPA! Eu sabia, maldito shell, encrenca com tudo!

Tsc... isso acontece porque o pipe | não foi informado como um 'pipe' e sim como a string "|" -- e o sort não conseguiu abrir o arquivo "|".
Este tipo de problema pode ser resolvido pelo eval -- ele interpreta novamente as strings na linha de comando.
$ eval "cat arquivo | $CMD"
bad interpreter
missing separator
parameter list too long
permission denied
set correct localle
unary operator expected


- Ah, agora funciona. Mas esse eval ai ficou feio...

Então vamos criar um alias para o comando!
$ alias cmd="sort | uniq"
$ cat arquivo | cmd
bad interpreter
missing separator
parameter list too long
permission denied
set correct localle
unary operator expected


Perceba que o comportamento do alias é diferente de uma variavel de ambiente. Devemos ficar atento à correta interpretação da nossa linha de comando pelo shell corrente, senão vamos ter resultados nem sempre amigáveis.

Ah, sim, o cat nesse exemplo é completamente supérfluo, poderia ser assim: 'sort arquivo | uniq'

- E o uniq precisa do sort ?

Sim... sem o sort ele fatalmente vai se perder, e é muito mais facil eliminar linhas repetidas que estejam em sequencia do que aleatórias. É bom dar uma lida no man destes comandos pois possuem opções muito poderosas!

2 comentários:

Alexsander disse...

Olá! muito boas as dicas q tens disponibilizado!
só uma sugestão:
"sort -u" também remove duplicidades.
abraços
t+

Tiago Peczenyj disse...

Claro, sort + uniq é um prato cheio!

Uma coisa interessante é nessa dupla é, por exemplo, imprimir apenas as linhas repetidas ou não repetidas de um texto (opções -u ou -d) e, quando a entrada vem ordenada, o resultado é extremamente confiável.

Entretanto não lembro se não existe algum furo no sort -u apenas, vou pesquisar.

Abração!