Как мне получить расширение файла от bash? Вот что я попробовал:
filename=`basename $filepath`
fileext=${filename##*.}
Делая это, я могу получить расширение bz2
от пути /dir/subdir/file.bz2
, но у меня есть проблема с путем /dir/subdir/file-1.0.tar.bz2
.
Я бы предпочел решение, использующее только bash без внешних программ, если это возможно.
Чтобы прояснить мой вопрос, я создавал bash-скрипт для извлечения любого данного архива только одной командой extract path_to_file
. Как извлечь файл, определяется сценарием, видя его тип сжатия или архивирования, который может быть .tar.gz, .gz, .bz2 и т. Д. Я думаю, что это должно включать в себя манипуляции со строками, например, если я получаю расширение, .gz
то я должен проверить, есть ли у него строка .tar
раньше .gz
- если это так, расширение должно быть .tar.gz
.
.tar.bz2
Ответы:
Если имя файла -
file-1.0.tar.bz2
расширениеbz2
. Метод, который вы используете для извлечения extension (fileext=${filename##*.}
), абсолютно корректен¹.Как вы решаете, что вы хотите, чтобы расширение было,
tar.bz2
а неbz2
или0.tar.bz2
? Вы должны ответить на этот вопрос в первую очередь. Затем вы можете выяснить, какая команда оболочки соответствует вашей спецификации.Одна из возможных спецификаций состоит в том, что расширения должны начинаться с буквы. Эта эвристика не работает для нескольких распространенных расширений
7z
, которые лучше всего рассматривать как особый случай. Вот реализация bash / ksh / zsh:Для переносимости POSIX вам нужно использовать
case
оператор для сопоставления с образцом.Другая возможная спецификация заключается в том, что некоторые расширения обозначают кодировки и указывают на необходимость дальнейшего удаления. Вот реализация bash / ksh / zsh (требуется
shopt -s extglob
под bash иsetopt ksh_glob
под zsh):Обратите внимание, что это считается
0
расширением вfile-1.0.gz
.¹ и связанные с ними конструкции находятся в POSIX , поэтому они работают в любой античной оболочке в стиле Борна, такой как ash, bash, ksh или zsh.
${VARIABLE##SUFFIX}
источник
.
токеном имеет тип архива, напримерtar
,0
должен ли конец ее не тип архива, такой как итерация..patch.lzma
. Лучше эвристический будет рассматривать строку после последнего.
: если это суффикс сжатия (.7z
,.bz2
,.gz
...), продолжают зачистки.Вы можете упростить ситуацию, просто выполнив сопоставление с шаблоном в имени файла, а не извлекая расширение дважды:
источник
Комментарии к этому здесь: http://liquidat.wordpress.com/2007/09/29/short-tip-get-file-extension-in-shell-script/
источник
.tar.gz
продленияВот мой пример: переведите точки в новые строки, пролистайте
tail
, получите последнюю строку:источник
Например:
источник
printf
в том случае, если имя файла содержит обратную косую черту или начинается с-
:"${filename#$(printf %s "$filename" | sed 's/\.[^[:digit:]].*$//g;')}"
Однажды я создал эти хитрые функции:
Я нашел этот простой подход, очень полезный во многих случаях, не только когда речь идет о расширениях.
Для проверки расширений - это просто и надежно
Для отсечки расширения:
Для изменения добавочного номера:
Или, если вам нравятся «удобные функции:
PS Если вам понравились эти функции или вы нашли их использованными полностью, пожалуйста, обратитесь к этому посту :) (и, надеюсь, оставьте комментарий).
источник
Ответ Джекмана, основанный на регистре, довольно хороший и переносимый, но если вы просто хотите указать имя файла и расширение в переменной, я нашел это решение:
Он работает только с двойными расширениями, и первым должно быть «tar».
Но вы можете изменить тестовую строку «tar» с помощью теста длины строки и повторить исправление несколько раз.
источник
я решил это с помощью этого:
но это работает только для известного типа архивации, в данном случае только
tar
источник