无法在 Perl 中打开子目录中的文件
Can't open files in subdirectories in Perl
我真的很难过。我是 Perl 的新手,我完全无法尝试遍历所有子目录,执行操作。它在根目录(我的脚本所在的位置)中工作正常,但是一旦到达子目录,它就会爆炸。我试过在 " 或 ' 或 q{} 中围绕文件名无济于事。我在 Whosebug 上搜索了这个问题,人们说它应该可以正常工作,打开处理子目录并将接受正斜杠。
一旦进入目录并尝试打开'./Horse/Models.meta',它就会在第一次打开(读取文件)时失败。这是在它处理了与我的脚本相同级别的 20 个文件之后。有什么想法吗?
use 5.010;
use strict;
use warnings;
use File::Find;
find(sub {
if (-f and /\.meta$/) {
print "--> " . $File::Find::name . "\n";
open my $in, '<', $File::Find::name or die "Can't read old file: $!";
open my $out, '>', "$File::Find::name.new" or die "Can't write new file: $!";
while( <$in> )
{
if(index($_," assetBundleName:")!=-1) {
print $out " assetBundleName: mobs\n";
} else {
print $out $_;
}
}
close $out;
print("mv -f \"" . $File::Find::name . ".new\" \"" . $File::Find::name . "\"\n");
system("mv -f \"" . $File::Find::name . ".new\" \"" . $File::Find::name . "\"");
}
}, '.');
只需使用
rename "$File::Find::name.new", $File::Find::name or die $!;
参见rename。
如果您想使用相对路径(即 $File::Find::name)而不只是文件名(即 $_),您需要指定
find({ wanted => sub { ... },
no_chdir => 1,
}, '.');
$File::Find::name
是文件相对于原始 CWD 的完整路径名,但 File::Find
会不断更改 CWD,除非您另有说明。告诉 File::Find 不要使用 no_chdir => 1
更改 CWD,或者使用 $_
而不是 $File::Find::name
。我推荐前者。
顺便说一句,您应该使用以下方法重命名文件,而不是删除文件。
rename($old_name, $new_name)
or die("Can't rename \"$old_name\" \"$new_name\": $!\n");
如果您需要跨文件系统边界重命名文件,您可以使用 File::Copy 的 move
,但如果操作得当,那么删除也不是那么糟糕:
system("mv", "-f", "--", $old_name, $new_name);
die("Error executing mv: $!\n") if $? == -1;
die("mv killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("mv returned error ".( $? >> 8 )."\n") if $? >> 8;
我真的很难过。我是 Perl 的新手,我完全无法尝试遍历所有子目录,执行操作。它在根目录(我的脚本所在的位置)中工作正常,但是一旦到达子目录,它就会爆炸。我试过在 " 或 ' 或 q{} 中围绕文件名无济于事。我在 Whosebug 上搜索了这个问题,人们说它应该可以正常工作,打开处理子目录并将接受正斜杠。 一旦进入目录并尝试打开'./Horse/Models.meta',它就会在第一次打开(读取文件)时失败。这是在它处理了与我的脚本相同级别的 20 个文件之后。有什么想法吗?
use 5.010;
use strict;
use warnings;
use File::Find;
find(sub {
if (-f and /\.meta$/) {
print "--> " . $File::Find::name . "\n";
open my $in, '<', $File::Find::name or die "Can't read old file: $!";
open my $out, '>', "$File::Find::name.new" or die "Can't write new file: $!";
while( <$in> )
{
if(index($_," assetBundleName:")!=-1) {
print $out " assetBundleName: mobs\n";
} else {
print $out $_;
}
}
close $out;
print("mv -f \"" . $File::Find::name . ".new\" \"" . $File::Find::name . "\"\n");
system("mv -f \"" . $File::Find::name . ".new\" \"" . $File::Find::name . "\"");
}
}, '.');
只需使用
rename "$File::Find::name.new", $File::Find::name or die $!;
参见rename。
如果您想使用相对路径(即 $File::Find::name)而不只是文件名(即 $_),您需要指定
find({ wanted => sub { ... },
no_chdir => 1,
}, '.');
$File::Find::name
是文件相对于原始 CWD 的完整路径名,但 File::Find
会不断更改 CWD,除非您另有说明。告诉 File::Find 不要使用 no_chdir => 1
更改 CWD,或者使用 $_
而不是 $File::Find::name
。我推荐前者。
顺便说一句,您应该使用以下方法重命名文件,而不是删除文件。
rename($old_name, $new_name)
or die("Can't rename \"$old_name\" \"$new_name\": $!\n");
如果您需要跨文件系统边界重命名文件,您可以使用 File::Copy 的 move
,但如果操作得当,那么删除也不是那么糟糕:
system("mv", "-f", "--", $old_name, $new_name);
die("Error executing mv: $!\n") if $? == -1;
die("mv killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("mv returned error ".( $? >> 8 )."\n") if $? >> 8;