Я планирую загрузить несколько изображений с веб-сайта, у которых нет расширения, поэтому я хочу добавить его на основе содержимого файла или MIME-типа.
file <filename>
отлично справляется с определением типа файла, однако мне нужно расширение.
--extension
Print a slash-separated list of valid extensions for the file type found.
Это из file
страницы руководства, но, похоже, это не работает:
$ file --extension test_text_file.txt
test_text_file.txt: ???
$ file --extension test_png_file.png
test_png_file.png: ???
$ file --extension test_gif_file.gif
test_gif_file.gif: ???
Он буквально печатает ???
для каждого файла, который я ему передаю, даже те, которые уже имеют правильное расширение. Все это допустимые файлы своих типов и прекрасно распознаются file
без --extension
.
Почему file --extension
у меня не работает и что я могу использовать, чтобы узнать расширение файла?
Идеей было бы использовать, file --mime-type
а затем создать массив таблиц диспетчеризации, который сопоставляет известные типы MIME с их расширениями, но я бы предпочел более простое и безопасное решение.
решение1
Почему
file --extension
у меня не работает?
Не только для вас. Смотритеэтот вопрос. Один из комментариев там кажется правильным:
Может быть, это просто очень-очень неполная характеристика?
Я не нашел стандартного инструмента Unix для выполнения конвертации, так что ваша идея может оказаться самым простым решением.
Идеей было бы использовать,
file --mime-type
а затем создать массив таблиц диспетчеризации, который сопоставляет известные типы MIME с их расширениями, но я бы предпочел более простое и безопасное решение.
Обратите внимание, что такая карта существует, это /etc/mime.types
. Смотритеэто еще один вопрос по Unix & Linux SE. На основе одного из ответов я придумал следующую функцию:
function getext() {
[ "$#" != 1 ] && { echo "Wrong number of arguments. Provide exactly one." >&2; return 254; }
[ -r "$1" ] || { echo "Not a file, nonexistent or unreadable." >&2; return 1; }
grep "^$(file -b --mime-type "$1")"$'\t' /etc/mime.types |
awk -F '\t+' '{print $2}'
}
Использование:
getext test_text_file.txt # it takes just one argument
Адаптируйте его под свои нужды, сделайте его сценарием и т. д. Основные проблемы:
- В случае успеха (статус выхода
0
) вывод может быть непустым или пустым (даже не\n
). - Некоторые mime-типы возвращают более одного расширения. Вы можете использовать
cut -d ' ' -f 1
, чтобы получить максимум одно, хотя это может быть не то, что вам нужно. Так что пользовательский файл карты вместо
/etc/mime.types
может быть полезен. Эта команда покажет вам, какие типы mime существуют в текущем каталоге (и подкаталогах):find . -type f -exec file -b --mime-type {} + | sort | uniq
grep
не должно совпадать более одного раза (по крайней мере с/etc/mime.types
);^
(начало строки) и$'\t'
(табуляция) существуют для избежания частичного совпадения. Используйтеgrep -m 1 ...
(илиhead -n 1
позже), чтобы быть уверенным, что вы получите не более одной строки.
решение2
Думаю, стоит упомянуть, что он показывает расширение для нескольких типов файлов.
file --preserve-date --special-files --extension *
Результат:
BMP_file: ???
CPP_file: ???
FIFO_file: ERROR: (null)
GZ_file: ???
HAR_file: ???
H_file: ???
HTML_file: ???
JAR_file: zip/cbz
JAVA_CLASS_file: ???
JAVA_JAVA_file: ???
JPG_file: jpeg/jpg/jpe/jfif
MKV_file: ???
MP3_file: ???
MP4_file: ???
ODT_file: ???
PDF_file: ???
PNG_file: ???
PPS_file: ???
SHELL_SCRIPT_file: ???
SO_file: ???
TIFF_file: ???
TMP_file_GBQcW: ???
XML_file: ???
ZIP_file: zip/cbz