Você já olhou para um grande diretório de nomes de arquivos e temeu a ideia de renomear todos eles? Ou talvez seus scripts estejam repletos de instruções condicionais para verificar se existe uma variável de ambiente. Bash fornece uma sintaxe concisa para alterar strings que torna a vida mais fácil. Elas são chamadas de expansões de parâmetros e mostrarei como usá-las.
Em um nível básico, a expansão de parâmetros significa transformar a sintaxe do Bash em um valor – expandindo-o. Por exemplo:
echo "$foo"Esta variável simples se transforma em seu valor atribuído. No entanto, é a forma menos útil de expansão de parâmetros e existem dezenas de outras que oferecem mais utilidade. Abordarei os mais importantes e apresentarei cenários do mundo real onde eles são eficazes. Conforme sua conveniência, você pode usá-los em scripts ou na linha de comando.
HTG Wrapped 2025: 24 dias de tecnologia
24 dias de nossos hardwares, gadgets e tecnologia favoritos
Mudança de caso
Você pode alterar a caixa de uma string inteira, ou parte dela, usando apenas o Bash.
O básico
Mude uma string inteira para maiúscula usando “^^”:
name="Hello, World!" echo "${name^^}"Mude o primeiro caractere para maiúsculo usando “^”:
name="hello, World!" echo "${name^}"Altere toda a string para minúsculas usando “,,”:
name="HELLO, WORLD!" echo "${name,,}"Mude a primeira letra para minúscula usando “,”:
name="Hello, world!" echo "${name,}"Exemplos do mundo real
Como usamos isso na prática?
Em um cenário, você pode encontrar muitos arquivos com nomes de arquivo em letras maiúsculas indesejáveis (por exemplo, IMG_2025-01-01.jpg) e deseja renomeá-los em lote para letras minúsculas:
for file in IMG_*.jpg; do mv "$file" "${file,,}" doneIsso também colocará em letras minúsculas as extensões de arquivo (abordadas posteriormente) e os caminhos (se incluídos).
Agora imagine um documento de texto cujos itens deveriam estar em letras maiúsculas. Por exemplo, uma lista de endereços MAC:
while read mac; do echo "${mac^^}" done < mac_addresses.txt > mac_addresses_upper.txtÀs vezes, crio prompts para meus scripts avaliarem respostas sim ou não. É melhor converter a string antes da comparação em vez de escrever múltiplas cláusulas:
read -p "Continue? (Y/n): " answer if [[ "${answer^^}" == "N" ]]; then echo "Stopping..." exit 1 fi # This is yes!Usando valores padrão
Encontrar variáveis não definidas é comum durante a criação de scripts. Muitas vezes o seu script precisa fazer perguntas sobre valores antes de usá-los. Isso pode sobrecarregar seu código com declarações condicionais desagradáveis. Felizmente, o Bash tem uma maneira concisa de gerenciar esses cenários.
O básico
Se uma variável não estiver definida ou estiver vazia, você poderá retornar a um valor padrão com “:-“:
echo "${NAME:-value}"Com um simples “-” (sem dois pontos), você pode voltar a um valor padrão se a variável nunca tiver sido declarada (não definida):
echo "${NAME-value}"O operador “:+” é o oposto de “:-“: retroceda se “NAME” estiver definido e não vazio:
export NAME="foo" echo "${NAME:+value}"Para “+”, “NAME” deve estar definido ou vazio antes de retornar ao valor padrão:
export NAME="foo" echo "${NAME+value}"O operador “=” é um pouco diferente, pois faz duas coisas: define e retorna o valor. Para “:=”, o Bash faz isso se “NAME” não estiver definido ou estiver vazio:
# "NAME" is unset at this point. echo "${NAME:=value}" # Expands to "value", but also sets "NAME" to "value". echo "$NAME" # "NAME" is now set to "value"Quando excluímos os dois pontos (“=”), significa definir e retornar o valor quando “NOME” não for definido:
echo "${NAME=value}" echo "$NAME"Como essas regras são confusas, aqui está um resumo:
# Fallback to the default if "NAME"... echo "${NAME:-value}" # Is unset or empty. echo "${NAME-value}" # Is unset. echo "${NAME:+value}" # Is set and not empty. echo "${NAME+value}" # Is set or empty. echo "${NAME:=value}" # Is unset or empty. (Also, assign to "NAME.") echo "${NAME=value}" # Is unset. (Also, assign to "NAME.")Exemplos do mundo real
A maneira sensata de localizar diretórios iniciais comuns é usar as constantes fornecidas pela especificação de diretório base XDG (também conhecida como XDG BDS), fornecida por freedesktop.org. No entanto, eles nem sempre estão definidos, então devemos voltar a um padrão sensato:
mv foo.conf "${XDG_CONFIG_HOME:-$HOME/.config}"Talvez o seu script tenha operações de arquivo subsequentes e você não queira se repetir:
mv foo.conf "${XDG_CONFIG_HOME:=$HOME/.config}" # Also sets a value. mv bar.conf "$XDG_CONFIG_HOME" # We don't need to check.Se ainda não estiver definido, isso atribuirá o valor XDG apropriado no primeiro uso.
Você pode até usar a expansão de parâmetros como uma condicional embutida e barata:
export DEBUG=true # MUST "export" if executing in the CLI. echo "Running script${DEBUG:+ (debugging enabled)}..." # Extra message, if debugging.Isto imprimirá uma mensagem especial somente quando a depuração estiver ativa.
Alterando partes de uma string
Substituir parte de uma string é comum na linha de comando, e não apenas em scripts. Por exemplo, alteração em massa de nomes de arquivos ou manipulação de entrada do usuário. Freqüentemente usaríamos sed, mas o bash possui suporte integrado para correspondência de padrões que é mais conveniente e às vezes mais rápido.
O básico
Substituir a primeira ocorrência de uma string é simples usando “/”:
text="Hello, World!" echo "${text/World/Universe}"Mas você pode substituir todos ocorrências usando “//”:
text="Hello, World! Hello, Universe!" echo "${text//Hello/Goodbye}"Você pode até substituir o início de uma string (se corresponder) por “/#”:
text="Hello, World!" echo "${text/#Hello/Goodbye}"Ou você pode substituir o final de uma string correspondente usando “/%”:
text="Hello, World!" echo "${text/%World!/Universe!}"Certifique-se de escapar dos caracteres especiais problemáticos (“!”), porque às vezes eles têm um significado especial e confundem o shell.
Você também pode remover partes de strings. O “#” removerá a instância correspondente mais curta:
file="foofoo.txt" echo "${file#foo}"Vamos executar novamente o comando anterior incluindo um curinga para corresponder ao máximo possível da string:
file="foofoo.txt" echo "${file#foo*}"Observe que os resultados são os mesmos? Isso porque “#” é preguiçoso e corresponderá o mínimo possível. Correspondeu a “foo” e depois desistiu. O curinga não teve efeito.
Por outro lado, usar “##” remove a correspondência mais longa possível (também conhecida como gananciosa):
file="foofoo.txt" echo "${file##foo*}"Esse padrão correspondeu a toda a string, portanto não há saída.
Os operadores “%” e “%%” funcionam da mesma forma que “#” e “##”, exceto no sentido inverso. Em vez de trabalharem da esquerda para a direita, movem-se da direita para a esquerda.
O operador “%” remove a correspondência mais curta possível, da direita para a esquerda:
file="foo.bar.txt" echo "${file%.*}"O padrão “.*” corresponderá a um ponto final e a qualquer coisa depois dele. Na string, notou que há dois pontos (três segmentos), mas apenas o segmento mais à direita foi correspondido?
Um “%%” remove a correspondência mais longa possível, da direita para a esquerda:
file="foo.bar.txt" echo "${file%%.*}"Esse é o mesmo padrão, exceto que usa “%%”. Ele se moveu da direita para a esquerda, correspondendo a “.*” conforme avançava. O segmento mais à esquerda não corresponde porque não começa com ponto final.
Esta também foi uma seção complicada, por isso merece uma folha de dicas:
echo "${var/pattern/value}" # "/" Replace the first occurrence. echo "${var//pattern/value}" # "//" Replace all occurrences. echo "${var/#pattern/value}" # "/#" Replace at the start. echo "${var/%pattern/value}" # "/%" Replace at the end. echo "${var#pattern}" # "#" Remove the shortest match (left to right). echo "${var##pattern}" # "##" Remove the longest match (left to right). echo "${var%pattern}" # "%" Remove the shortest match (right to left). echo "${var%%pattern}" # "%%" Remove the longest match (right to left).
Como obter uma folha de dicas para qualquer comando no terminal Linux
Às vezes, trapacear é necessário.
Exemplos do mundo real
Imagine que você tem uma lista de arquivos e deseja alterar sua extensão:
for f in *.txt; do mv "$f" "${f/%.txt/.md}" done“%” substitui o final de uma string.
Sua câmera digital cria imagens com um prefixo irritante, então você deseja removê-las:
for f in IMG_*.jpg; do mv "$f" "${f#IMG_}" done“#” remove o início de uma string.
Talvez você tenha um caminho para um arquivo e queira apenas o nome do arquivo:
path="/home/user/documents/report.pdf" echo "${path##*/}"“##” remove a correspondência mais longa, o que permite um curinga ganancioso, combinando até a última barra.
Talvez você queira apenas a extensão do arquivo:
filename="archive.tar.gz" echo "${filename##*.}"Por último, talvez você queira o nome base de um arquivo sem a extensão:
filename="document.tar.gz" echo "${filename%%.*}"“%%” é ganancioso, da direita para a esquerda, parando no último segmento (esquerda).
O arquivo Linux .bashrc: o que é, além de 6 coisas que você pode fazer com ele
O arquivo de controle de execução do Bash é muito legal e confiável.
Para mim, as expansões de parâmetros não são diferentes de um conceito geral de programação chamado expressões. Significa simplesmente transformar um trecho de código em um valor em tempo de execução. É um conceito valioso que pode melhorar seus scripts. Ele pode potencialmente minimizar o uso de instruções condicionais ou retardar desnecessariamente chamadas para ferramentas externas (como sed).
Você pode misturar e combinar expansões de parâmetros conforme necessário. Por exemplo, você pode incorporá-los:
echo "${FOO:-${BAR:-bar}}"O padrão será “bar” se nem “FOO” nem “BAR” estiverem definidos. Tenha em mente que embora as declarações condicionais sejam feias, às vezes são mais fáceis de ler. Portanto, se você estiver aninhando profundamente expansões de parâmetros, repense sua abordagem e considere códigos “mais burros”, como instruções condicionais.
8 funções essenciais do shell para melhorar sua linha de comando do Linux
Há uma função para todos.