Как я могу получить расширение (я) файла на основе его содержимого?

293
confetti

Я планирую загрузить кучу изображений с веб-сайта, которые не имеют расширения, поэтому я хочу добавить его в зависимости от содержимого файла или 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-типы на их расширения, но я бы предпочел иметь более простое и безопасное решение.

0
Я предполагаю, что вы пытались удалить расширение из имени файла, а затем запустили `file` против него? Appleoddity 5 лет назад 0
Да. Выходные данные одинаковы для каждого файла. confetti 5 лет назад 0
Какая у вас версия файла? файл - версия cybernard 5 лет назад 0
@cybernard `file-5.33` confetti 5 лет назад 0

1 ответ на вопрос

1
Kamil Maciorowski

Почему 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+' '' } 

Использование:

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позже), чтобы убедиться, что вы получите не более одной строки.

Большое спасибо за этот отличный ответ и подсказку к `/ etc / mime.types`, для меня это прекрасно работает. confetti 5 лет назад 0

Похожие вопросы