Pages

Sunday, October 28, 2012

Compactando arquivos no terminal do GNU/Linux

Há quase dois anos eu me dediquei a modificar uma função de descompactação de arquivos comumente encontrada na internet para uma um pouco mais geral, que me permitisse descompactar em um único comando vários arquivos e que também podem ter formatos diferentes. Você pode encontrar essa função nesse texto.

Hoje, eu criei a função inversa. A que me permite fazer compactação de arquivos sem ter que pensar muito em qual comando tenho que digitar. A função segue abaixo.
   compact() {
     if [ "$#" -ge "1" ]; then
        case "$1" in
          *.[tT][aA][rR].[bB][zZ]|*.[tT][bB][zZ])
                  local file="$1"; shift; tar jcvf "$file" "$@" ;;
          *.[tT][aA][rR].[bB][zZ]2|*.[tT][bB][zZ]2)
                   local file="$1"; shift; tar jcvf "$file" "$@" ;;
          *.[tT][aA][rR].[gG][zZ]|*.[tT][gG][zZ]) 
                   local file="$1"; shift; tar zcvf "$file" "$@" ;;
          *.[gG][tT][gG][zZ]) 
                   local file="$1"; shift; tar zcvf "$file" "$@" ;;
          *[bB][zZ]2)                           
                   shift; bzip2 -z -k "$@"  ;;
          *.[rR][aA][rR])
                    local file="$1"; shift; rar a -r "$file"  "$@" ;;
          *[gG][zZ])                           
                     shift; gzip -r "$@"  ;;
          *.[tT][aA][rR]) 
                     local file="$1"; shift; tar cvf "$file" "$@" ;;
          *.[zZ][iI][pP])
                     local file="$1"; shift; zip -r "$file" "$@" ;;
          *.7[zZ])
                     local file="$1"; shift; 7z a -r "$file" "$@" ;;
          *.[xX][zZ]) 
                     local file="$1"; shift; tar Jcvf "$file" "$@" ;;
          *)    echo "don't know how to compact '$i' ..." ;;
        esac
      else
        echo "Insufficient arguments."
      fi ; }
Novamente, para usar a função basta copiar esse texto e adicioná-la no seu ~/.bashrc O uso dessa função é bastante simples. Basta, no terminal, digitar:

compact arquivo_compactado.EXTENSÃO lista de arquivos para compactar

Onde, arquivo_compactado.EXTENSÃO é no nome do arquivo final (quando aplicável -- eu chego lá para explicar isso) seguido de sua extensão. Exemplos.: arquivo.tar.bz2, arquivo.tgz, arquivo.zip, arquivo.rar ...

 Esta regra NÃO é aplicável no caso de compactação direta no forma .gz ou .bz2. Nesse caso comando compacta o próprio arquivo no local dele, ou seja, o arquivo chamado zezinho.txt, torna-se zezinho.txt.gz ou zezinho.txt.bz2. Por esse motivo, o nome do arquivo compactado não faz sentido aqui e o comando fica sendo:

compact EXTENSÃO lista de arquivos para compactar

Onde extensão indica o tipo de compactação, nesse caso, apenas com bz2 e gz isso faz sentido.
A lista de arquivos aceita espaço no nome dos arquivos e permite recursividade emdiretórios em todos os formatos, exceto, o bzip2. Sendo que alerto que no caso da compactação com o gz isso irá criar 'n' arquivos de formato .gz e não apenas 1 único arquivo final. Se quer compactar com o .gz e ter apenas um arquivo no final, na verdade, mesmo sem saber, está querendo usar o .tar.gz. O mesmo se aplica para o caso do bzip2, mas eu não consegui fazer ele tratar recursividade em diretórios.

Limitações
Há algumas limitações. A primeira delas é que existem vários níveis de compressão, várias opções que não foram escritas. Exemplo, é possível compactar arquivos com o zip usando criptografia, basta, para isso, adicionar a opção 'e' no comando. Eu não fiz isso, logo, esse comando não permite ao usuário compactar com criptografia. Da mesma forma, os níveis de compactação estão no nível padrão para todos os formatos.

Quem já abriu a manpage de qualquer um desses programas sabe que eles fazem muito mais do que o que foi escrito acima, mas eu nunca usei nenhum das opções adicionais para compactação, assim, quando escrevi o básico, escrevi algo que funcionará muito bem para mim.

Alerto para o uso da compactação com o gzip e o bzip2. Se nunca usou esse tipo de compactação pura, antes de fazer qualquer coisa nos seus arquivos de trabalho, faça testes, verifique o resultado e procure entender o que acontece. Não use esses comandos sem entendê-los antes. 

Convite
Enquanto escrevia a função, ficava claro para mim que há muito espaço para aprimoramentos. Fiz o melhor que pude hoje, mas convido a todos que se interessarem a contribuírem com a melhoria da função.

4 comments:

  1. O título da postagem deveria ser "compactando arquivos com um único comando".
    Mas gostei bastante!

    ReplyDelete
    Replies
    1. Puxa... é verdade... não tinha pensado nisso. Mas agora que já foi publicado e começou a ser indexado vai ficar assim mesmo...

      Delete
  2. Caro Mitre, mandou super bem, vou dar uma olhada para mandar sugestões, valeu!

    ReplyDelete
    Replies
    1. Sérgio, sua colaboração será muito bem vinda.

      Enquanto programava algumas coisas vieram a cabeça: como passar argumentos adicionais para os comandos de forma 'facultativa' e/ou como remover argumentos, por exemplo, a opção 'v' (verbose) do comando tar caso fosse do meu interesse (é sempre interessante fazer isso quando há muitos arquivos).

      Outro problema é o tratamento de erros. Simplesmente não há. E por isso destaquei um alerta para o uso dos comando gzip e bzip2. Nos outros, os riscos são mínimos, nesses comandos, se digitados da forma errada no diretório errado, pode danificar o 'home' do usuário.

      Eu queria unir as duas primeiras opções do 'case' em uma apenas sem fazer uma linha gigante (observação válida para o comando 'extract' do outro tópico). Eu não sei como fazer isso (deve ser algo bem simples, né ? mas não procurei na documentação). Da mesma forma, unir o .gtgz com o .tgz sem adicionar outro "ou" a ponto do case.

      Bom, essas foram as minhas ideias que não foram implementadas. Minha próxima função será uma bem parecida com essa, mas com o objetivo de listar o conteúdo dos arquivos e acabo de pensar em melhorar também a função extract (com algumas das dicas que pensei acima e com outras, ainda não amadurecidas e que dependem da função de listar!).

      Enfim, sua colaboração será muito bem vinda ! Um abraço,

      Delete