May 26, 2007

Comandos mais usados

O comando abaixo permite ver de maneira simples quais os comandos que você executa mais frequentemente no linux:
history | awk '{print $2}' | awk 'BEGIN {FS="|"} {print $1}'| \
        sort | uniq -c | sort -rn| head -10 
Só por diversão é comum alguns hackers verificarem seus comandos mais comuns e postarem em algum lugar. O Dorneles postou seus comandos mais comuns, e de quebra mostrou uma implementação em Python.

Como Lisp não é (erroneamente) considerada uma linguagem apropriada para escrever scripts de sistema eu gosto de fazer uma uma versão em Lisp de scripts como esse para ver como ela se sai. A minha implementação pode ser vista abaixo. Eu usei apenas ANSI Common Lisp. Se eu tivesse usado bibliotecas externas o código poderia ser ainda mais compacto.

(defun get-comandos ()
  (with-open-file (stream "/home/kroger/.bash_history")
    (loop for line = (read-line stream nil nil) while line
       collect (subseq line 0 (position #\Space line)))))

(defun conta-itens ()
  (let ((comandos (get-comandos)))
    (mapcar (lambda (item) (list (count item comandos :test #'string=) item))
            (remove-duplicates comandos :test #'string=))))

(format t "~{~{~a ~}~%~}" (sort (conta-itens) #'> :key #'first))
O objetivo aqui não é, naturalmente, fazer uma comparação com python (no estilo "minha linguagem é melhor que a sua"), mas sim ver como Lisp se sai nesse tipo de coisa. Eu acho que o resultado foi bem satisfatório. Lisp não tem nenhum comando padrão para ler todo o arquivo em uma string, mas dá para fazer isso com apenas 2 linhas de código. A função count conta quantas vezes um item aparece em uma sequencia, de modo que foi possivel implementar o código para contar os elementos de uma maneira funcional.

Um pouco de estatísticas: a implementação de python tem 14 linhas e 46 caracteres, enquanto a implementação em lisp tem 10 linhas e 52 caracteres. A implementação em lisp é mais curta, porém mais densa.

Eu não tenho dúvidas que é possível escrever um código em python ainda menor, mas como eu disse anteriormente, esse não é o objetivo aqui. Meu objetivo foi mostrar como é possível escrever um código simples, curto, e elegante em Lisp para lidar com coisas corriqueiras do dia-a-dia.

Posted at 12:15