我計劃從不附帶擴展名的網站下載一堆圖像,因此我想根據文件的內容或 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
without完美識別--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