Linux / Comando basename: extrair nomes e remover sufixos de caminhos
basename extrai o último componente de um caminho, retirando a parte dos diretórios e, se solicitado, um sufixo conhecido. Ele trabalha com o texto recebido: não abre, renomeia nem verifica a existência do arquivo. Use-o para obter um nome de exibição ou preparar texto em scripts, mantendo os argumentos entre aspas quando necessário.
Os exemplos usam a implementação de basename do GNU Coreutils em um shell Bash. O formato básico de um nome e um sufixo também é padronizado por POSIX (Portable Operating System Interface), norma de interfaces para sistemas do tipo Unix; as opções GNU serão identificadas. Caminhos como /data/archive.tar.gz podem ser fictícios, pois os comandos abaixo não precisam que os arquivos existam.
O que é o comando basename?
Use basename quando você precisar apenas do último componente de um caminho.
basename /home/user/report.txt
A saída é a seguinte.
report.txt
O comando interpreta o separador /, sem consultar se o caminho representa arquivo, diretório ou link. Ele remove barras finais e extrai o último componente. Não resolve links simbólicos nem transforma o texto em um caminho absoluto. Caminhos Windows com barras invertidas não seguem automaticamente essas mesmas regras.
Sintaxe e uso básico
basename nome [sufixo]
basename opções nome ...
Na sinopse, colchetes indicam uma parte opcional e reticências indicam repetição: não os copie literalmente. O primeiro formato recebe um nome e um sufixo opcional. No GNU, use -a para tratar vários nomes, como explicado adiante. Estes três comandos básicos são independentes:
basename /var/log/nginx/access.log
basename /home/user/Documents/
basename relative/path/file.txt
As saídas, na ordem, são access.log, Documents e file.txt. No GNU, basename / resulta em /, e basename "" escreve uma linha vazia. A entrada especial // pode ter tratamento diferente entre plataformas; não a normalize presumindo um resultado universal.
Remover um sufixo
Informar o sufixo no segundo argumento
O segundo argumento só é removido quando coincide literalmente com o final do último componente e não é igual ao componente inteiro. Por exemplo, basename report.txt .txt resulta em report, mas basename .txt .txt mantém .txt. Essa exceção está definida na especificação POSIX de basename.
basename /data/archive.tar.gz .gz
basename /home/user/report.txt .txt
Os resultados dos dois comandos são, respectivamente, archive.tar e report. Para retirar o sufixo composto inteiro, indique .tar.gz; o próximo comando deve produzir archive:
basename /data/archive.tar.gz .tar.gz
Retirar o sufixo de vários nomes com -s
A opção GNU basename -s ou --suffix especifica o sufixo como uma opção. Usar esta opção também ativa o comportamento -a para processar múltiplos nomes juntos.
basename -s .jpg /images/a.jpg /backup/b.jpg
basename --suffix=.log /var/log/app.log /tmp/test.log
Os quatro resultados, na ordem, são a, b, app e test. Um sufixo ausente ou com diferença de maiúsculas e minúsculas deixa o nome inalterado. Ele não é uma expressão regular nem um padrão de curingas; coloque um sufixo como "*.log" entre aspas se realmente quiser comparar esses caracteres literalmente.
Processar vários caminhos
Usar -a para vários nomes
As opções GNU -a e --multiple tratam todos os argumentos seguintes como nomes. Sem elas, o segundo argumento do formato básico é um sufixo, não outro caminho. Ao combinar vários nomes e remoção de sufixo, use -s. Mantenha as opções antes dos nomes, como orienta o manual GNU de basename.
basename -a /srv/www/index.html /var/log/syslog /home/user
A saída assume a seguinte forma.
index.html
syslog
user
Separar resultados com NUL usando -z
Um nome de arquivo Unix pode conter uma quebra de linha. A extensão GNU -z, ou --zero, termina cada resultado com um byte nulo, NUL, em vez de uma nova linha. Assim, um programa que leia registros NUL consegue distinguir o separador das quebras de linha que pertencem ao nome.
basename -z -a /data/file1 /data/file2
Este comando escreve os bytes de file1, NUL, file2 e NUL, sem duas linhas de texto convencionais. O programa consumidor também precisa aceitar esse delimitador. Não guarde essa saída em uma variável Bash com $(...): variáveis do shell não preservam bytes NUL. A opção não elimina a necessidade de passar cada caminho de entrada como um argumento separado e entre aspas.
Comparar basename e dirname
| Entrada | basename |
dirname |
|---|---|---|
/home/user/report.txt |
report.txt |
/home/user |
docs/manual.pdf |
manual.pdf |
docs |
notes.txt |
notes.txt |
. |
/ |
/ |
/ |
A tabela compara a extração do nome com a parte de diretório; ambos trabalham sobre texto. Reunir as saídas com uma barra não garante reconstruir a grafia original, pois barras finais ou repetidas podem ser simplificadas. O guia de comandos Linux por tarefa apresenta outras ferramentas para consultar e manipular caminhos.
Tratar extensões de arquivo
Remover uma extensão conhecida
Quando o sufixo conhecido representa a extensão que deseja retirar, passe-o como segundo argumento. Os comandos abaixo devem imprimir photo e backup, sem alterar arquivos:
basename photo.webp .webp
basename backup.tar.gz .tar.gz
Em basename report.txt.bak .txt, a saída continua sendo report.txt.bak, porque .txt não está no final. Barras finais do caminho são tratadas antes da comparação; um sufixo que contenha / não corresponde ao último componente.
Distinguir pontos e extensões
Só porque um nome de arquivo tem um ponto não significa que ele sempre tenha uma extensão. Existem arquivos ocultos começando com um ponto como .profile, arquivos com múltiplos sufixos como archive.tar.gz, e nomes que terminam com ponto.
Defina quais sufixos a aplicação reconhece. Um ponto é apenas parte do nome; o comando não identifica o formato real do conteúdo. Não use a extensão obtida como prova de tipo ou validade de um arquivo recebido.
Usar em scripts Bash
Obter um nome para exibição
Salve o script completo abaixo como extract-name.sh e execute bash extract-name.sh "/srv/uploads/annual report.pdf". Ele requer Bash e basename disponível no caminho de busca de comandos. O resultado esperado é Nome: annual report.pdf; o arquivo indicado não precisa existir.
#!/usr/bin/env bash
if [ "$#" -ne 1 ]; then
printf '%s\n' 'Uso: bash extract-name.sh CAMINHO' >&2
exit 2
fi
path=$1
name=$(basename -- "$path") || {
printf '%s\n' 'Não foi possível extrair o nome.' >&2
exit 1
}
printf 'Nome: %s\n' "$name"
-- encerra as opções, permitindo nomes que comecem com hífen. As aspas em "$path" evitam divisão por espaços e expansão de curingas. O script retorna 2 por quantidade incorreta de argumentos e 1 se a consulta falhar. A substituição de comando remove quebras de linha finais; este exemplo de exibição não preserva fielmente todos os nomes Unix possíveis. Para registros com esses nomes, use o fluxo NUL de -z com um consumidor apropriado.
Comparar com a expansão de parâmetros
A expansão de parâmetros do shell permite retirar um prefixo sem iniciar basename. Em ${path##*/}, o padrão */ corresponde ao maior prefixo que termina em barra, e ## remove esse prefixo. O trecho abaixo é completo e imprime report.pdf:
path='/srv/uploads/report.pdf'
name=${path##*/}
printf '%s\n' "$name"
Essa expansão não aplica todas as regras de basename. Se path for /srv/uploads/ ou /, ${path##*/} resulta em texto vazio, enquanto GNU basename retorna uploads ou /. Use a expansão simples somente quando essas condições de entrada forem adequadas à tarefa.
Opções principais
| Opção | Descrição |
|---|---|
-a, --multiple |
Lida com múltiplos nomes e produz cada resultado. |
-s sufixo, --suffix=sufixo |
Remove um sufixo final correspondente, sem apagar o nome inteiro, e ativa o processamento de vários nomes. |
-z, --zero |
Termina cada resultado com um caractere NUL em vez de uma nova linha. |
--help |
Exibe o uso e as opções suportadas. |
--version |
Imprime a versão instalada do GNU Coreutils. |
-a, -s e -z são extensões GNU. Confira basename --version e basename --help onde houver GNU Coreutils. Em outros sistemas Unix, consulte a implementação local e prefira o formato básico definido por POSIX quando a portabilidade for necessária.
Problemas comuns
Resultado mesmo sem arquivo existente
Isso é um comportamento normal. basename extrai a última parte da string de entrada sem verificar a existência do arquivo. Se a operação exigir um arquivo real, você deve verificar separadamente a existência e as permissões.
Caminho com espaços dividido em argumentos
Sem aspas, espaços podem separar um caminho em vários argumentos e caracteres como * podem ser expandidos pelo shell antes de chegar ao comando. O trecho abaixo define primeiro o valor e depois o passa como um argumento único:
path='/srv/uploads/annual report.pdf'
basename -- "$path"
Sufixo não removido
Confira o final exato do nome, as maiúsculas e minúsculas e as aspas usadas pelo shell. O sufixo é literal: .TXT difere de .txt, e "*.txt" não significa “qualquer extensão txt”. Se o sufixo for igual ao último componente inteiro, o nome também é preservado.
Perguntas frequentes
O comando basename renomeia o arquivo real?
Não. Ele apenas calcula e exibe o último nome da string do caminho de entrada sem alterar nenhum arquivo ou diretório.
O basename pode remover uma extensão?
Sim. basename report.txt .txt produz report. No GNU, basename -s .txt report.txt notes.txt trata dois nomes e produz report e notes. O segundo argumento do formato básico precisa estar separado do caminho por um espaço.
O basename funciona em um caminho inexistente?
Sim. Porque ele apenas processa a string do caminho, ele exibe o último componente mesmo se o arquivo real não existir.
Qual é a diferença em relação ao dirname?
basename imprime o último componente; dirname imprime a parte anterior. Para um nome simples como notes.txt, os resultados são notes.txt e ., respectivamente.




