В сценариях Bash одной из самых распространенных задач является манипуляция путями к файлам – особенно когда из полного пути нужно извлечь только имя файла. Именно здесь на помощь приходит команда basename. Несмотря на кажущуюся простоту, basename имеет мощные возможности при правильном использовании в более сложных сценариях, инструментах автоматизации, хостингах и средах CI/CD.
Команда basename удаляет путь к каталогу и, по желанию, расширение файла, оставляя только базовое имя (последний компонент пути к файлу).
Вот лишь несколько примеров реальных потребностей в сценариях:
Ведение журнала: Извлечь имя обрабатываемого файла журнала.
Архивирование: Добавление только имени файла в сжатый архив.
Автоматизация: Обработка партий файлов и генерация имен выходных файлов.
Конвейеры: Извлечение имен файлов на этапах CI/CD.
Этот скрипт перебирает файлы .log, извлекает имя без расширения и записывает каждое действие в журнал. basename упрощает работу с именами файлов без сложной нарезки строк.
Допустим, вы получаете полные пути из пользовательского ввода или от другого процесса:
#!/bin/bash
input_path="$1"
filename=$(basename "$input_path")
echo "The file name is: $filename"
Использование basename в скрипте обеспечивает гибкость при работе с динамическими путями к файлам, особенно в таких средах, как Linux VPS, где журналы, файлы конфигурации и резервные копии могут находиться в разных каталогах. Это делает ваш скрипт надежным независимо от того, передается ли ему полный путь, например /var/log/syslog, или относительный файл, например ./config.txt.
Используйте их вместе, чтобы выделить элементы пути:
#!/bin/bash
path="/etc/nginx/nginx.conf"
echo "Directory: $(dirname "$path")"
echo "Filename: $(basename "$path")"
Если вы хотите удалить известные расширения:
⚠️ Примечание: Это работает только при точном совпадении суффикса. Так что .txt работает, а .TXT или .tar.gz – нет, если они не указаны явно.
Для нескольких расширений используйте basename вместе с другими инструментами:
file="/tmp/data/archive.tar.gz"
filename=$(basename "$file")
clean_name=${filename%%.*}
echo "$clean_name"
# Output: archive
Или:
Хотя basename интуитивно понятен, он порождает подпроцесс. Для скриптов, критичных к производительности, или больших циклов предпочтите чистые альтернативы Bash:
✅ Быстрее, чем вызов внешнего basename.
Допустим, вы хотите снабдить все файлы .jpg префиксом с сегодняшней датой: