❯ file -p -n -b .*(.) *(.) | sort | uniq
ASCII text
ASCII text, with no line terminators
ASCII text, with very long lines
ASCII text, with very long lines, with no line terminators
data
empty
JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, Exif Standard: [TIFF image data, big-endian, direntries=0], baseline, precision 8, 96x96, components 3
JSON data
Non-ISO extended-ASCII text, with very long lines, with CRLF, LF line terminators, with escape sequences
Python script, UTF-8 Unicode text executable
UTF-8 Unicode text
UTF-8 Unicode text, with very long lines
very short file (no magic)
X11 Xauthority data
ext1;ASCII text
ext2;ASCII text, with no line terminators
ext3;ASCII text, with very long lines
ext4;ASCII text, with very long lines, with no line terminators
ext5;data
ext6;empty
ext7;JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, Exif Standard: [TIFF image data, big-endian, direntries=0], baseline, precision 8, 96x96, components 3
ext8;JSON data
ext9;Non-ISO extended-ASCII text, with very long lines, with CRLF, LF line terminators, with escape sequences
ext10;Python script, UTF-8 Unicode text executable
ext11;UTF-8 Unicode text
ext12;UTF-8 Unicode text, with very long lines
ext13;very short file (no magic)
ext14;X11 Xauthority data
fext () {
file -b --extension "$@" |
sed -e 's-^jpeg/jpg/jpe/jfif$-jpg-' |
sed -e 's-^pdf$-PDF-' |
cat
}
请原谅没用的cat。包含它是为了模块化,因此如果您有返回多个扩展名字符串的文件类型,您可以复制、粘贴和编辑该sed行以将这些倍数转换为您喜欢的单个扩展名,或者如果您愿意,可以任意大写,等等。在此示例中,由fileas标识的文件jpeg/jpg/jpe/jfif将被赋予扩展名jpg,而由 as 标识的文件pdf将被赋予扩展名PDF。这cat只是转换列表末尾的无操作占位符。
# using hard links
cp --link /path/to/originals /path/to/files
# using reflinks on supported file systems
cp --reflink=auto /path/to/originals /path/to/files
不容易。
file(1)
有一个--extension
选项,但在我的测试(Debian/bullseye)中,大多数文件都显示了问号(???
)。并且对于每个已知文件类型的编码
case..esac
很可能不会成功,因为file
似乎检测到至少 3000 种文件类型:首先,我会尝试获取给定目录中的文件类型列表:
注意,这里使用了zsh-globbing:
以下
find
行导致相同的输出:使用此列表,我将创建一种文件类型扩展映射/查找文件并使用它来重命名文件:
高温高压
使用
perl
-basedrename
和File::MimeInfo::Magic
perl 模块(在libfile-mimeinfo-perl
基于 Debian 的系统上的软件包中,通常默认安装在桌面安装中,因为它是 的依赖项(推荐)xdg-utils
):-n
(如果看起来正确,请删除for dry-run)。根据幻数猜测文件类型可以帮助解决这个问题。
请参考https://en.wikipedia.org/wiki/List_of_file_signatures
此页面列出了大多数文件类型及其幻数,您的脚本只是从偏移量中读取一些字节并与签名进行比较,然后添加相应的后缀。
此答案假定您有一个相对干净的文件名列表,全部位于一个目录中,并且文件名没有空格、制表符、换行符和其他不良字符。此处的代码片段适用于
bash
shell。首先,做好备份
每当您对数千个文件进行自动重命名时,总是有可能出现问题。一个问题乘以十万个文件就等于要解决十万个问题,然后才能重试。
首先进行备份:
现在,如果您有任何问题,您可以从备份中恢复:
file
变化很大该
file
命令的执行质量因发行版而异。似乎可以肯定的是,版本越新越好,因为使用的magic
文件file
可能会更新。如果可以的话,您可以通过将文件复制/rsync
-ing 到运行具有更好版本的file
.那么我的系统的
file
实现有多好呢?让我们定义一个函数
fext
,它将file -b --extension
在我们给它的任何通配符 glob 上运行。此外,我们将file
通过一些简单sed
的转换运行输出,file
以根据我们的喜好标准化输出:请原谅没用的
cat
。包含它是为了模块化,因此如果您有返回多个扩展名字符串的文件类型,您可以复制、粘贴和编辑该sed
行以将这些倍数转换为您喜欢的单个扩展名,或者如果您愿意,可以任意大写,等等。在此示例中,由file
as标识的文件jpeg/jpg/jpe/jfif
将被赋予扩展名jpg
,而由 as 标识的文件pdf
将被赋予扩展名PDF
。这cat
只是转换列表末尾的无操作占位符。其他具有多个扩展名的文件类型呢?
确保您已枚举您的集合中所有可能的文件类型并为其
file
返回多个扩展名,这一点很重要。这很容易测试:一定没有输出。如果有输出,您需要在定义中添加另一
sed
行fext
。现在,您可以
fext
针对您的整个文件集合运行,看看它认为它识别了多少,以及它没有识别多少。我正在使用一个包含 152 个弱选择文件的测试组。在三个系统上,我运行:
Ubuntu 18.04.2 LTS:
FreeBSD 13.1:
Ubuntu 22.04 LTS:
请注意,我们在实用程序
magic
使用的文件中发现了一个错误。file
幸运的是,这很容易在我们的fext
函数中修复:出色的。这里重要的是没有斜杠(或逗号!)。我们已经创建了一个粗略的量化指标,允许我们查看文件的百分比由
file
. 具体来说,file
无法识别 152 个文件中的 28 个,或略高于 18%。我们可以进一步细化我们的fext
功能,为那些file
无法识别的类型的文件分配默认扩展名。如果我们愿意,我们可以列出并查看 无法识别
grep
的文件的具体文件名:file
在我的(弱)样本集中,“未知”文件主要是 PostScript 文件。
file
确实如此标识它们,但该magic
文件没有为 PostScript 文件指定扩展名。因此,如果我们使用
fext
为每个文件提供扩展名,file
则无法识别的文件将获得扩展名unknown
.不幸的是,
file -b --extension
它不是很有帮助,因为它返回???
许多具有已知扩展名的格式。相反,首先克隆感兴趣的目录以防万一:然后在目录中创建一个 mime 类型列表:
输出如下所示:
现在创建一个
bash
脚本add_ext.sh
,如果需要,根据 mime 类型重命名具有适当扩展名的文件。chmod +x add_ext.sh
在使用find
对文件运行脚本之前不要忘记: