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

0

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

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

Ответы:

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

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