Хаа.. Привет! Сегодня будем извлекать расширение и имя файла на 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##*,}"



Проще уже не объяснишь. Если не дошло, сам потыкай на примерах и уже точно въедешь в тему, на практике само собой всё проще и понятнее.



Это один из способов реализовать желаемое. Но есть и другой. Давай воспользуется командой 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 — это встроенная команда оболочки, которая позволяет отображать или устанавливать переменные оболочки и среды.



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



tags: #bash #linux



🟢 Подпишись: @bashdays