尝试帮助我的岳父解决一个奇怪的问题:突然间,他新买的 MacBook Pro 上的大部分(可能 20%)iCloud Drive 文档都无法打开。我查看了一下,有问题的文件似乎是没有文件扩展名的文件。它们显示为“Unix 可执行文件”而不是 .doc 文件。
如果我进入并添加 .doc 作为文件扩展名,则文件会立即下载并正确打开。
有人见过这种情况吗?除了手动逐个重命名数百个文件之外,还有其他解决方案吗?
答案1
在 Mac OS 9 及更早版本中,Mac 唯一能知道文件类型的方式是通过文件“类型”和“创建者”代码。在 OS X 中,它改用扩展名,但这些代码仍然存在(可能可以覆盖最初的设置,但现在我认为它们是识别文件的“备用”方式)。
我刚刚将一个 DOC 文件(扩展名为 .doc)重命名为“Foo”(无扩展名),Finder 便识别了它。使用该xattr
命令,我能够看到原始文件中的代码已复制到新文件中,因此我的第一台 Mac 上的 Finder 可以打开它。
在另一台 Mac 上检查 Finder(通过 iCloud 同步),“Foo”文件是 UNIX 文件。因此,iCloud 不会从源同步扩展属性。如果没有扩展,您必须在目标端重新应用代码,或者只需添加扩展。
如果幸运的话,您已将 Word、Excel 等文件保存在单独的文件夹中,并且可以批量重命名(见下文)。如果不幸运的话,您可以file
对每个文件运行命令以查看其内容,然后手动重命名。
要批量重命名文件,我认为有很多工具可以做到这一点,或者您可以使用这个 Perl 脚本来做到这一点。这是我几年前写的,虽然很蹩脚,但它对我遇到的所有问题都有效。
#!/usr/bin/perl
use strict;
use File::Copy;
if (scalar(@ARGV) < 2) {
print "\nUSAGE: $0 <extension> <file(s)>\n\n";
exit 1;
}
my $ext = shift;
# Strip off leading period, since we'll add it later.
$ext =~ s/^\.//;
# Everytime I pass this script's @ARGV back out to a system call
# the whole argument arrary gets treated like a long string.
# If any individual $ARGV had spaces in it, that $ARGV ends up
# looking like multiple args to the system call.
# So, parse each $ARGV one at a time, in double-quotes.
foreach my $arg (@ARGV) {
if ($arg =~ m/\./) {
# This $arg already has an extension!
if ($arg =~ m/\.$ext$/) {
# This $arg already has this $ext. Skip it.
warn "WARNING! $arg already has that extension.\n";
next;
}
else {
# This $arg has an extension, but it's not the same as $ext.
warn "WARNING! $arg already had an extension.\n";
}
}
renameFile("\$", ".$ext", $arg);
}
sub renameFile {
my $searchString = shift;
my $replacementString = shift;
my $file = shift;
if (-e "$file") {
my $newName = $file;
if ($newName =~ s/$searchString/$replacementString/ge) {
if (-e "$newName") {
print "ERROR! Unable to move '$file' to '$newName' because\n";
print " a file named '$newName' already exists!\n";
}
else {
print "Moving '$file' to '$newName'.\n";
move("$file", "$newName") || die "Unable to rename '$file'.\nStopped";
}
}
}
else {
print "File '$file' does not exist.\n";
}
}