Postagem em destaque

Criando bot do Telegram em Shell script com ShellBot

Utilizando expansão de variáveis


Sobre
 

A expansão de variáveis é um recurso para manipulação de cadeia de caracteres armazenados em uma variável. Com ela podemos substituir trechos de uma expressão, extrair uma sequência de caracteres ou até mesmo converte-la. É útil quando precisamos manipular ou extrair uma cadeia sem o uso de comandos externos.

Para ativar o recurso é necessário utilizar o identificador da variável entre chaves.

Sintaxe
${variavel}

A inserção das chaves não torna a implementação do recurso como obrigatória, o que permite sua aplicação solitária. Exemplo. echo ${var} é a mesma coisa que echo $var. Mas a boa prática na utilização das chaves ‘{}’ facilita a percepção das variáveis em seu código ou até mesmo funcionando como um caractere de escape em uma expressão.


Expansão de strings

${var:N}
Imprime todos os caracteres a partir da posição ‘N’.
${var:N:M}
Imprime 'M' caracteres a partir da posição 'N'.
${var: -N}
Imprime os últimos ‘N’ caracteres.
${var: -N:M}
Imprime os últimos ‘N’ caracteres com ‘M’ comprimento.
${var: -N: -M}
Imprime os últimos ‘N’ caracteres com menos ‘M’ comprimento.
${var:N: -M}
Imprime os caracteres a partir da posição ‘N’ com menos ‘M’ comprimento.
${var/exp1/exp2}
Substitui ‘exp1’ por ‘exp2’ uma única vez.
${var//exp1/exp2}
Substitui ‘exp1’ por ‘exp2’ recursivo.
${var/#exp1/exp2}
Substitui ‘exp1’ por ‘exp2’ se estiver no inicio da expressão.
${var/%exp1/exp2}
Substitui ‘exp1’ por ‘exp2’ se estiver no final da expressão.
${var#exp}
Remove ‘exp’ se estiver no inicio da expressão.
${var%exp}
Remove ‘exp’ se estiver no final da expressão.
${var##*exp}
Remove tudo do inicio da expressão até ‘exp’ (inclusive).
${var%%exp*}
Remove tudo a partir de ‘exp’ em diante. (inclusive).
${var~}
Inverte a formatação do primeiro caractere da expressão.
${var~~}
Inverte a formatação de todos os caracteres da expressão.
${var^}
Converte o primeiro caractere da expressão em maiúsculo.
${var^^}
Converte todos os caracteres da expressão em maiúsculo.
${#var}
Retorna o comprimento da variável.
${var} O mesmo que $var. (não ambíguo)
${!exp*}
Retorna todas com nomes que começam com ‘exp’.


Expansão condicional

${var:-exp}
Imprime ‘exp’ se o valor da variável for nulo.
${var:+exp}
Imprime ‘exp’ se o valor da variável não for nulo.
${var:=exp}
Imprime ‘exp’ e armazena se o valor da variável for nulo.
${var:?exp}
Imprime mensagem de erro ‘exp’ se o valor da variável for nulo.

Vou mostrar alguns exemplos na aplicação desses recursos e no final você verá o quanto podem ser úteis e ajudar a reduzir seu código em determinadas situações.

Exemplos

1. Imprimindo todos os caracteres a partir de uma determina posição em diante.

1.1 Imprimindo tudo a partir da palavra ‘aprendendo’

$ echo ${var:7}
aprendendo shell script.

1.2 Imprimindo somente a palavra ‘shell script.’
echo ${var:17}
shell script.

Aproveitando que estamos neste ponto, quero explicar com o recurso de expansão trata a posição do caractere em uma expressão. Toda cadeia de caracteres começa na posição ‘0’ e não ‘1’ como imaginamos. Considere a frase:

Estou aprendendo shell script.

Representação da posição de cada caractere na expressão.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
E
s
t
o
u
a
p
r
e
n
d
e
n
d
o
s
h
e
l
l
s
c
r
i
p
t
.

Dessa forma podemos notar que a primeira letra da expressão esta armazenada na posição '0', a segunda na posição '1' e assim por diante.

Por essa razão no exemplo 1.1, quando executamos o comando echo ${var:6} foi retornado a expressão ‘aprendendo shell script.’. Se olharmos na tabela, veremos que o caractere ‘a’ na palavra ‘aprendendo’ está na posição 6.

Isso quer dizer que se quiséssemos imprimir todos os caracteres com exceção do primeiro, devemos executar dessa forma:
$ echo ${var:1}
prendendo shell script.


2. Obtendo o comprimento da expressão armazenada.

2.1 Imprimindo o total de caracteres.
$ var=’Estou aprendendo shell script.’
$ echo ${#var}
30
Ele retorna o total de caracteres armazenados na variável ‘var’. Se a variável estiver vazia, retorna ‘0’.

3. Imprimindo uma cadeia de caracteres a partir de uma posição com um determinado comprimento.

3.1 Imprimindo somente a palavra ‘shell’.
$ var=’Estou aprendendo shell script.’
$ echo ${var:17:5}
shell
A palavra ‘shell’ possui apenas 5 caracteres e inicia na posição ‘17’

3.2 Caso deseje imprimir a expressão ‘shell script’, devemos considerar o ‘ ‘ espaço com um caractere também.
$ var=’Estou aprendendo shell script.’
$ echo ${var:17:12}
shell script
Se somar os caracteres da expressão ‘shell’ com ‘script’, teremos 11 caracteres no total; mais 1 caractere contando com o espaço, no final teremos 12.

4. Substituindo uma determinada expressão por outra uma única vez

4.1 Substituindo a palavra ‘shell’ por ‘java’.
$ var=’Estou aprendendo shell script.’
$ echo ${var/shell/java}
Estou aprendendo java script.
A alteração só ocorrerá na primeira expressão encontrada.

4.2 Substituindo a palavra ‘shell script’ por ‘Linux’.
$ var=’Estou aprendendo shell script.’
$ echo ${var/shell script/Linux}
Estou aprendendo Linux.
Em casos de expressões compostas, não há necessidade do uso das aspas; pois elas seriam consideradas como parte da expressão.


5. Substituindo uma expressão recursivamente.

5.1 Substituindo todas as letras ‘s’ da expressão por ‘S’ maiúsculo.
$ var=’Estou aprendendo shell script.’
$ echo ${var//s/S}
EStou aprendendo Shell Script.
A alteração ocorre recursivamente na expressão. A sintaxe é semelhante ao recurso anterior, porém utiliza-se duas barras
(//) ao invés de uma.

5.2 Removendo todos os espaços da expressão.
$ echo ${var// /}
$ var=’Estou aprendendo shell script.’
Estouaprendendoshellscript.
Simplesmente omitindo a cadeia de caracteres que ficaria no lugar, ou seja, tire isso e não coloque nada.


6. Removendo uma cadeia de caracteres antes de uma determinada expressão. (recursivo)


6.1 Removendo todos os caracteres antes da letrada ‘o’.
$ var=’Estou aprendendo shell script.’
$ echo ${var##*o}
shell script.
A remoção dos caracteres é executada da esquerda para direita, até a última ocorrência da letra ‘o’ na expressão.
O meta-caractere ‘*’ (asterisco) quer dizer tudo.

6.2 Extraindo a extensão de um arquivo.
$ file='/home/shaman/arquivo.txt'
$ echo ${file##*.}
txt
Tudo que havia antes do ‘.’ (ponto) foi removido, inclusive o próprio ponto. No final foi retornado somente a extensão.

7. Removendo uma cadeia de caracteres depois de uma determinada expressão. (recursivo)


7.1 Removendo todos os caracteres depois da letra 'o'.
$ var=’Estou aprendendo shell script.’
echo ${var%%o*}
Est
A remoção dos caracteres é executada da direita para esquerda até a última ocorrência da
letra ‘o’ na expressão.

7.2 Removendo a extensão do arquivo.
$ file=/home/shaman/arquivo.txt
$ echo ${file%%.*}
/home/shaman/arquivo

8 Invertendo a formatação de uma cadeia de caracteres.
 

 8.1 Invertendo a formatação do primeiro caractere.
$ echo ${var~}
$ var=’Estou aprendendo shell script.’
estou aprendendo shell script.
A letra ‘E’ do inicio da expressão foi convertida para minúsculo ‘e’.

8.2 Invertendo a formação de todos os caracteres da expressão. (recursivo)
$ echo ${var~~}
$ var=’Estou aprendendo shell script.’
eSTOU APRENDENDO SHELL SCRIPT.
A formatação de cada caractere da expressão foi invertida. O que era minúsculo passou para maiúsculo e vice-versa.

9. Convertendo uma cadeia ou cadeia de caracteres para maiúsculo.

9.1 Convertendo a primeira letra da expressão para maiúsculo.

$ var=’juliano’
$ echo ${var^}
Juliano

9.2 Convertendo todos os caracteres em maiúsculo. (recursivo)
$ var=’juliano’
$ echo ${var^^}
JULIANO

10. Retornando uma cadeia de caracteres se o valor da variável for nulo.


10.1 Imprimir ‘Não tem nada aqui’ se a variável ‘msg’ estiver vazia.

$ msg=””
$ echo ${msg:-Não tem nada aqui}
Não tem nada aqui
Se o valor da variável for nulo, retorna a expressão informada. Caso contrário retorna o conteúdo da variável.


11. Retornando uma cadeia de caracteres se o valor da variável não for nulo.

11.1 Imprimindo ‘Tem alguma coisa’ se a variável ‘msg’ não estiver vazia.

$ msg=”shell script”
$ echo ${msg:+Tem alguma coisa}
Tem alguma coisa
Se o valor da variável não for nulo, retorna a expressão informada. Caso contrário, retorna
nulo.


12. Imprimindo e armazenando a expressão na variável caso seu valor seja nulo.

12.1 Imprimindo e armazenando a expressão ‘novo valor’ na variável ‘msg’, caso seu valor seja nulo.
$ msg=””
$ echo ${msg:=novo valor}
novo valor
$ echo $msg
novo valor
Além de retornar a expressão, ela foi armazenada na variável.


13. Imprimindo mensagem de erro se o valor da variável for nulo.

13.1 Imprime a mensagem de erro ‘Valor não encontrado’ se o valor da variável ‘msg’ for nulo.
$ msg=””
$ echo ${msg:?Valor não encontrado.}
bash: msg: Valor não encontrado.
Note que foi retornado uma mensagem de erro semelhante a do interpretador de comando.


Aplicação prática

Montei alguns exemplos de aplicações práticas do recurso de expansão de variáveis. Perceberá que sua utilização é fácil e ao mesmo tempo poderosa.

Todos os exemplos a seguir são apenas simulados, ou seja, nenhuma alteração é realizada.


A função 'add_usuario' simula a criação de uma conta de usuário com base no primeiro nome do usuário.
function add_usuario()
{
    # Limpa a tela.
    clear

    echo 'Criar conta de usuário'
    echo

    # Lê os dados e armazena em 'NOME'.
    read -p 'Nome completo :' NOME
    echo

    # Se o valor da variável 'NOME' for nulo, assume 
    # o valor padrão 'usuario' e insere um sufixo número aleatório.
    NOME=${NOME:-usuario$RANDOM}

    echo 'Dados da conta a ser criada'
    echo 'Nome completo:' $NOME

    # Extrai o primeiro nome e armazena em 'USUARIO'
    USUARIO=${NOME%% *}

    # Imprime as informações.
    echo 'usuario:' $USUARIO
    echo 'home: /home/'$USUARIO
    echo
    echo 'comando:'
    echo '$ sudo adduser' $USUARIO

    return 0
    # FIM
}

Testando.
$ add_usuario
Criar conta de usuário
Nome completo :Ronaldo de Oliveira Martins
Dados da conta a ser criada
Nome completo: Ronaldo de Oliveira Martins
usuario: Ronaldo
home: /home/Ronaldo

comando:
$ sudo adduser Ronaldo
A expansão ${NOME%% *} apaga recursivamente todos os caracteres depois do espaço, sobrando apenas o primeiro nome; que é usado para criação da conta de usuário e definições do home.


Adicionando um usuário sem informar o nome.
$ add_usuario
Criar conta de usuário
Nome completo :
Dados da conta a ser criada
Nome completo: usuario5454
usuario: usuario5454
home: /home/usuario5454

comando:
$ sudo adduser usuario5454
Quando o nome do usuário é omitido, a expansão ${NOME:-usuario$RANDOM} insere o valor 'usuario' seguido de um número aleatório armazenado na variável de ambiente $RANDOM.


A função 'arq_maiusculo' renomeia os arquivos do diretório informado, convertendo os nomes para maiúsculo exceto a extensão.
function arq_maiusculo()
{
    # Diretório padrão é o atual.
    DIR=${1:-.}

    # Título
    echo "Comando:"


    # Lê todos os arquivo do diretório.
    ls -1 "$DIR" | while read ARQUIVO
    do
        # Salva a extensão do arquivo
        EXT="${ARQUIVO##*.}"

        # Salva o nome do arquivo
        ARQNOME="${ARQUIVO%%.*}"

        # Converte o nome do arquivo para maiúsculo e insere o '.' (ponto)
        # no final do nome se o arquivo possuir extensão.
        echo "$ mv '$ARQUIVO' '${ARQNOME^^}${EXT:+.$EXT}'"
    done
    # FIM
}

Testando...
$ arq_maiusculo
Comando:
$ mv 'music10.mp3' 'MUSIC10.mp3'
$ mv 'music1.mp3' 'MUSIC1.mp3'
$ mv 'music2.mp3' 'MUSIC2.mp3'
$ mv 'music3.mp3' 'MUSIC3.mp3'
$ mv 'music4.mp3' 'MUSIC4.mp3'
$ mv 'music5.mp3' 'MUSIC5.mp3'
$ mv 'music6.mp3' 'MUSIC6.mp3'
$ mv 'music7.mp3' 'MUSIC7.mp3'
$ mv 'music8.mp3' 'MUSIC8.mp3'
$ mv 'music9.mp3' 'MUSIC9.mp3'
A função separa a extensão do nome do arquivo para realizar a conversão do nome para maiúsculo sem afetá-la e no final concatena as partes, inserindo o carácter '.' ponto antes da extensão, se ela existir.
 

A função 'arq_permissao' retorna as permissões do arquivo informado.
function arq_permissao()
{
    # Armazena o nome do arquivo, caso seja omitido
    # imrpime mensagem de erro e finaliza a função.
    ARQUIVO=${1:?Requer nome do arquivo.}

    # Verifica se é um arquivo.
    [ -f "$ARQUIVO" ] || { echo 'Arquivo não encontrado ou inválido.'; return 1; }

    # Inicializa o array, armazenando as informações do arquivo.
    INFO=($(ls -l "$ARQUIVO"))

    # Imprime as informações
    echo 'Informações'
    echo 
    echo 'Arquivo: ' "'$ARQUIVO'"
    echo 'Usuário: ' ${INFO[2]}        # Imprime o usuário dono do arquivo armazenado no indice 2 do array.
    echo
    echo 'Permissões'                  # Extrai os caracteres contendo a permissão do:
    echo 'Dono: ' ${INFO[0]:1:3}       # Dono 
    echo 'Grupo: ' ${INFO[0]:4:3}      # Grupo
    echo 'Outros: ' ${INFO[0]:7:3}     # Outros

    return 0
    #FIM
}

Testando
$ arq_permissao music3.mp3
Informações
Arquivo:  music3.mp3
Usuário:  juliano
Permissões
Dono:  rw-
Grupo:  rw-
Outros:  r--
No indice ${INFO[0]} está a expressão contendo as permissões do arquivo. Exemplo: '-rw-rw-r--'. Utilizando a expansão ${INFO[0]:N:M}, consigo extrair os 'M' caracteres na posição 'N' que são as partes que se referem ao dono, grupo ou outros.

Executando a função sem argumentos.
$ arq_permissao
bash: 1: Requer nome do arquivo.
A expansão ${1?:...} finaliza a função caso o valor de '$1' for nulo.
 
Apesar de não ter mostrado exemplos de todos os recursos de expansão, mas acredito que o resumo foi suficiente para você se ligar na sua eficiência. E tenho certeza que brevemente você estará dominando a parada ou se já domina. 😀😁😎😎

Comentários

Contato

Nome

E-mail *

Mensagem *