You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl如何在指定目录及其所有上级父目录中搜索名为.cfg的文件

路径向上搜索配置文件的优化实现与递归方案

原有实现依赖手动统计路径斜杠数量、正则拆分路径,存在跨平台兼容性差、路径带末尾斜杠时匹配错误、停止搜索条件硬编码灵活性低的问题,以下是两种优化实现:

优化迭代实现(生产环境推荐)

使用Perl核心模块File::Spec处理路径逻辑,无需手动解析路径规则,兼容性更强,性能也优于递归实现:

use File::Spec;

sub get_p4_config_updir {
    my ($client_root, $cfg_file) = @_;
    my $cur_dir = $client_root;
    while (1) {
        # 拼接当前目录下的目标文件完整路径
        my $target_path = File::Spec->catfile($cur_dir, $cfg_file);
        return $cur_dir if -e $target_path;
        
        # 获取上级目录
        my $parent_dir = File::Spec->catdir($cur_dir, File::Spec->updir());
        # 已经到达根目录时停止搜索
        last if File::Spec->canonpath($parent_dir) eq File::Spec->canonpath($cur_dir);
        
        $cur_dir = $parent_dir;
    }
    return "";
}

# 调用方式和原有逻辑完全一致
my $cfg = '.cfg';
my $dir = '/user/home/wkspace/abc/def/MAIN';
my $path = get_p4_config_updir($dir, $cfg);
if ($path ne "") {
  printf("**** File exists in dir: $path ****\n");
} else {
  printf("**** File not found ****\n");
}

递归实现方案

如果需要用递归逻辑实现,可参考以下代码:

use File::Spec;

sub get_p4_config_updir_recursive {
    my ($cur_dir, $cfg_file) = @_;
    # 先检查当前目录是否存在目标文件
    my $target_path = File::Spec->catfile($cur_dir, $cfg_file);
    return $cur_dir if -e $target_path;
    
    # 获取上级目录
    my $parent_dir = File::Spec->catdir($cur_dir, File::Spec->updir());
    # 到达根目录仍未找到则返回空
    return "" if File::Spec->canonpath($parent_dir) eq File::Spec->canonpath($cur_dir);
    
    # 递归搜索上级目录
    return get_p4_config_updir_recursive($parent_dir, $cfg_file);
}

# 调用示例
my $cfg = '.cfg';
my $dir = '/user/home/wkspace/abc/def/MAIN';
my $path = get_p4_config_updir_recursive($dir, $cfg);
print $path ? "**** File exists in dir: $path ****\n" : "**** File not found ****\n";

两种实现都支持跨平台运行,兼容带末尾斜杠的输入路径,默认搜索到根目录为止,如果你需要限制向上搜索的层级,可以自行增加计数变量控制搜索深度。

内容的提问来源于stack exchange,提问作者Stacker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:06:00