você está aqui: Home  → Colunistas  →  Cantinho do Shell

 

Algumas implementações do Bash 4.0

Por Júlio Cezar Neves

Data de Publicação: 23 de Maio de 2010

1. Novas substituições de parâmetros

  • ${parâmetro:n}

    Equivale a um cut com a opção -c, porém muito mais rápido. Preste a atenção, pois neste caso, a origem da contagem é zero.

      $ TimeBom=Flamengo
      $ echo ${TimeBom:3}
      mengo
    

    Essa Expansão de Parâmetros que acabamos de ver, também pode extrair uma sub cadeia, do fim para o principio, desde que seu segundo argumento seja negativo.
      $ echo ${TimeBom: -5} 
      mengo 
      $ echo ${TimeBom:-5} 
      Flamengo 
      $ echo ${TimeBom:(-5)} 
      mengo
    
  • ${!parâmetro}

    Isto equivale a uma indireção, ou seja devolve o valor apontado por uma variável cujo nome está armazenada em parâmetro.

    Exemplo
      $ Ponteiro=VariavelApontada
      $ VariavelApontada="Valor Indireto"
      $ echo "A variável \$Ponteiro aponta para \"$Ponteiro\"
      > que indiretamente aponta para \"${!Ponteiro}\""
    
    A variável $Ponteiro aponta para "VariavelApontada" que indiretamente aponta para "Valor Indireto"

  • ${!parâmetro@}
  • ${!parâmetro*}

    Ambas expandem para os nomes das variáveis prefixadas por parâmetro. Não notei nenhuma diferença no uso das duas sintaxes.

    Exemplos

    Vamos listar as variáveis do sistema começadas com a cadeia GNOME:
      $ echo ${!GNOME@}
      GNOME_DESKTOP_SESSION_ID GNOME_KEYRING_PID GNOME_KEYRING_SOCKET
      $ echo ${!GNOME*}
      GNOME_DESKTOP_SESSION_ID GNOME_KEYRING_PID GNOME_KEYRING_SOCKET
    

  • ${parâmetro^}
  • ${parâmetro,}

    Essas expansões foram introduzidas a partir do Bash 4.0 e modificam a caixa das letras do texto que está sendo expandido. Quando usamos circunflexo (^), a expansão é feita para maiúsculas e quando usamos vírgula (,), a expansão é feita para minúsculas.

    Exemplo
      $ Nome="botelho"
      $ echo ${Nome^} 
      Botelho
      $ echo ${Nome^^} 
      BOTELHO 
      
      $ Nome="botelho carvalho"
      $ echo ${Nome^} 
      Botelho carvalho 	# Que pena...
    
    Um fragmento de script que pode facilitar a sua vida:
      read -p "Deseja continuar (s/n)? "
      [[ ${REPLY^} == N ]] && exit
    
    Esta forma evita testarmos se a resposta dada foi um N (maiúsculo) ou um n (minúsculo).

    No Windows, além dos vírus e da instabilidade, também são frequentes nomes de arquivos com espaços em branco e quase todos em maiúsculas. No exemplo anterior, vimos como trocar os espaços em branco por sublinha (_), no próximo veremos como passá-los para minúsculas:
      $ cat trocacase.sh
      #!/bin/bash 
      #  Se o nome do arquivo tiver pelo menos uma 
      #+ letra maiúscula, troca-a para minúscula 
       
      for Arq in *[A-Z]*	# Pelo menos 1 minúscula
      do
          if  [ -f "${Arq,,}" ]	# Arq em minúsculas já existe?
          then
              echo ${Arq,,} já existe
      else
          mv "$Arq" "${Arq,,}"
          fi
      done
    

2. Substituição de chaves

Elas são usadas para gerar cadeias arbitrárias, produzindo todas as combinações possíveis, levando em consideração os prefixos e sufixos.

Existiam 5 sintaxes distintas, porém o Bash 4.0 incorporou uma 6ª. Elas são escritas da seguinte forma:

  1. {lista}, onde lista são cadeias separadas por vírgulas;
  2. {inicio..fim};
  3. prefixo{****}, onde os asteriscos (****) podem ser substituídos por lista ou por um par inicio..fim;
  4. {****}sufixo, onde os asteriscos (****) podem ser substituídos por lista ou por um par inicio..fim;
  5. prefixo{****}sufixo, onde os asteriscos (****) podem ser substituídos por lista ou por um par inicio..fim;
  6. {inicio..fim..incr}, onde incr é o incremento (ou razão, ou passo). Esta foi introduzida a partir do Bash 4.0.

      $ echo {1..A}	# Letra e número não funfa
      {1..A}
      $ echo {0..15..3}	# Incremento de 3, só no Bash 4
      0 3 6 9 12 15
      $ echo {G..A..2}	# Incremento de 2 decresc, só no Bash 4
      G E C A
      $ echo {000..100..10}	# Zeros à esquerda, só no Bash 4
      000 010 020 030 040 050 060 070 080 090 100
      $ eval \>{a..c}.{ok,err}\;
      $ ls ?.* 
      a.err  a.ok  b.err  b.ok  c.err  c.ok
    
    A sintaxe deste último exemplo pode parecer rebuscada, mas substitua o eval por echo e verá que aparece:
      $ echo \>{a..c}.{ok,err}\; 
      >a.ok; >a.err; >b.ok; >b.err; >c.ok; >c.err;
    
    Ou seja o comando para o Bash criar os 6 arquivos. A função do eval é executar este comando que foi montado. O mesmo pode ser feito da seguinte maneira:

      $ touch {a..z}.{ok,err}
    

    Mas no primeiro caso, usamos Bash puro, o que torna esta forma pelo menos 100 vezes mais rápida que a segunda que usa um comando externo (touch).

Recomende este artigo nas redes sociais

 

 

Veja a relação completa dos artigos desta coluna