我打算从没有扩展名的网站下载一堆图像,所以我想根据文件的内容或 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-type 会返回多个扩展名。您可以使用它
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