【问题标题】:Can't open files in subdirectories in Perl无法在 Perl 的子目录中打开文件
【发布时间】:2017-09-06 20:34:44
【问题描述】:

我真的很难过。我是 Perl 的新手,我完全被困在试图遍历所有子目录,执行操作。它在根目录(我的脚本所在的位置)中运行良好,但是一旦它到达子目录,它就会爆炸。我尝试将文件名包含在 " 或 ' 或 q{} 中,但无济于事。我在 StackOverflow 上搜索了这个问题,人们说它应该可以正常工作,打开处理子目录并接受正斜杠。 一旦进入目录并尝试打开“./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 . "\"");

  }
}, '.');

【问题讨论】:

  • “炸弹”是什么意思?
  • 请不要使用"bombs""failing""doesn't work"等。它根本没有提供有关问题可能是什么的有用信息。

标签: perl file subdirectory


【解决方案1】:

随便用

rename "$File::Find::name.new", $File::Find::name or die $!;

rename

如果您想使用相对路径(即 $File::Find::name)而不仅仅是文件名(即 $_),则需要指定

find({ wanted   => sub { ... },
       no_chdir => 1,
}, '.');

【讨论】:

  • 谢谢,我会改的。但是,这仍然不能解释为什么打开我的 $in, '
  • “失败”是什么意思?你得到什么错误?
  • 无法读取旧文件:setAssetBund.pl 第 11 行没有这样的文件或目录。
  • 好的,添加并再次运行:无法读取旧文件:(./Animals Horses/Models.meta) setAssetBund.pl 第 11 行没有这样的文件或目录。(注意:一些更改目录结构更改了子目录中遇到的第一个文件,但仍然存在相同的问题)这个文件的名称中也有空格。
  • 谢谢!!这行得通!我不知道 no_chdir
【解决方案2】:

$File::Find::name 是文件相对于原始 CWD 的完整路径名,但 File::Find 会不断更改 CWD,除非您另有说明。使用no_chdir =&gt; 1 告诉File::Find 不要更改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;

【讨论】:

  • 谢谢!! no_chdir 是我所缺少的。我没有意识到它正在改变我身上的 cwd!
  • 这无关紧要,但你写 0x7F 而不是十进制版本有什么原因吗?我在perlvar 中没有看到这个用于$?,我很好奇它是否重要。
猜你喜欢
  • 1970-01-01
  • 2022-01-07
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-11
  • 1970-01-01
相关资源
最近更新 更多