você está aqui: Home  → Arquivo de Mensagens

Ebook Gratuito: Dá para fazer em Shell?, com o Prof. Julio Neves

Controle de Laço

Colaboração: Gustavo Chaves

Data de Publicação: 15 de Setembro de 1998

O Gustavo mandou uma colaboração indicando uma maneira melhor de realizar um comando sobre múltiplos arquivos. A seguir a íntegra da mensagem:

  Queiroz> #!/bin/sh
  Queiroz> for file in ""find . -name \*.txt -print"" do
  Queiroz>    mv $file ""dirname $file""/""basename $file .txt"".doc
  Queiroz> done
Olá Queiroz.
Há algum tempo eu lhe mandei uma ``meta-dica'' a respeito do livro
`UNIX Power Tools', da O'Reilly.  Uma das dicas mais legais que eu
aprendi com ele foi uma maneira de otimizar este loop.  Vamos
simplificar e imaginar que você esteja no diretório contendo arquivos
com extensão "".C' e que você queira trocá-las por"".cc'.  Antes de ler
o livro eu fazia o seguinte:
        for i in *.C
        do mv $i ""basename $i .C"".cc
        done
Note que pra cada arquivo são invocados dois processos: o basename e o
mv.  A dica do livro mostra como fazer isto invocando apenas três
processos e mais um pra cada arquivo.  Veja:
         ls *.C | sed 's/\(.*\).C$/mv \1.C \1.cc/' | sh
O ls gera a lista dos arquivos a serem renomeados, um por linha, e os
passa ao sed que produz, para cada arquivo, um comando mv apropriado.
Estes comandos mv são passados para uma instância da shell que os
executa em seqüência, sem loop.  Se a lista tiver mais que três
arquivos você já estará economizando ativações de processos.
O que eu achei genial foi usar o sed pra construir um script
on-the-fly e passá-lo para uma outra instância da shell.  É fácil
aplicar este truque em outras situações.  O difícil (pelo menos para
mim) seria tê-lo descoberto sozinho.


Veja a relação completa dos artigos de Gustavo Chaves