Хаа.. Привет! Сегодня будем извлекать расширение и имя файла на bash. Для чего? А почему бы и нет! На самом деле это нужно знать, это база. Я часто вижу как это делают люди с помощью какой-то зиготы (регулярки/awk/sed), ну боль же. Не надо ничего усложнять, есть вещи на порядок выше.

Что такое имя файла и расширение, объяснять не буду, как говорил мой техдир — заебал, если интересно, сходи погугли.

Теперь по делу. Берем какой-нибудь подопытный файл, пусть будет: bashdays.gzip и накидываем скрипт.

#!/bin/bash

FILE="bashdays.gzip"

FIRST="${FILE%.*}"
SECOND="${FILE##*.}"

echo $FIRST
echo $SECOND

В переменной FILE заносим имя файла bashdays с расширением gzip. Далее в переменной FIRST отсекаем расширение gzip, в переменной SECOND отсекаем имя bashdays. По итогу на экран выведется такая шляпа:

bashdays
gzip

Понял? Легкотня, без гигантских регулярок и гавнокода. Сейчас объясню подробнее, что происходит.

Символ %.* означает отсекание всего после точки. Символ ##*. ну а тут наоборот, отсекание всего до точки.

Если бы файл назывался bashdays,gzip (через запятую), то наш скрипт, нужно было бы немного адаптировать под эту запятую.

FIRST="${FILE%,*}"
SECOND="${FILE##*,}"
Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Проще уже не объяснишь. Если не дошло, сам потыкай на примерах и уже точно въедешь в тему, на практике само собой всё проще и понятнее.

Это один из способов реализовать желаемое. Но есть и другой. Давай воспользуемся командой basename.

Команда basename в Linux печатает последний компонент в пути к файлу. Это особенно полезно в скриптах bash, где вы хотите извлечь имя файла из длинного пути к файлу.

Если тебе заранее известно расширение файла, в нашем случае оно известно как gzip. То мы сможем отсечь расширение такими способами (они идентичны):

basename /tmp/bashdays.gzip .gzip
basename -s .gzip /tmp/bashdays.gzip

В обоих случаях на экран выведется: bashdays

Ключ -s удаляет завершающее расширение файла, но можно и из коробки запускать, не указывая его.

Еще есть ключ -a, в который можно передать несколько путей и извлечь сразу пачку. Но я ни разу не видел, чтобы такое использовали где-то, так что можно забить.

С basename вроде всё, дальше у нас по списку dirname.

Команда dirname в Linux печатает путь к файлу с удаленным последним компонентом. Это в основном дает вам путь к каталогу из пути к файлу.

dirname /usr/local/sbin
dirname /tmp/bashdays.gzip
dirname /usr/bin/date

Результат будет таким:

/usr/local/
/tmp/
/usr/bin/

Ну а чо, вообще шикарно! Ну и вишня для гиков, магия с переменной $IFS.

Переменная IFS (внутренний разделитель полей) используется для указания определенного разделителя для разделения строк.

_file="/tmp/bashdays.gzip"

OLDIFS="$IFS"
IFS='.'
set -- $_file
IFS="$OLDIFS"

printf "File: %s\nExt: %s\n" "$1" "$2"

Кратенько: Определяем имя файла, задаем переменную IFS для извлечения имени файла и расширения, указываем разделитель «.» (точка), выполняем set для разделения на позиционные параметры, ну и выводим все на экран с помощью printf (но можно и через echo).

Выхлоп скрипта будет таким:

File: /tmp/bashdays
Ext: gzip

Команда set — это встроенная команда оболочки, которая позволяет отображать или устанавливать переменные оболочки и среды.

Уффф.. Как-то много букв получилось, пардон. Основные моменты рассмотрели, надеюсь твой интерес я удовлетворил. Спасибо за внимание, ставь лайк. А вечером закину еще что-нибудь занимательное. Давай, на связи!