如何在目錄及其所有父目錄中搜索名為“.cfg”的檔案我正在獲取名稱如下代碼,但我想知道是否有更好的方法來做到這一點。我也想知道遞回的方式來做同樣的事情。
sub get_p4_config_updir($ $)
{
my ($client_root, $cfg_file) = @_;
# Dir from where search starts - it's a client root here
my $cur_dir = $client_root;
printf("**** cur_dir: $cur_dir ****\n");
my $slashes = $cur_dir =~ y/\///;
printf("**** no of back slashes: $slashes ****\n");
while($slashes > 2) {
my ($parent_dir, $b) = $cur_dir =~ /(.*)\/(.*)/;
printf("**** parent_dir: $parent_dir, b: $b ****\n");
$slashes--;
if (-e "$cur_dir/$cfg_file") {
printf("**** File exists in dir: $cur_dir ****\n");
return $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");
}
uj5u.com熱心網友回復:
使用示例Path::Tiny:
#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
use Path::Tiny;
# Returns a Path::Tiny object to the directory containing the file
# being looked for, or undef if not found.
sub get_p4_config_updir {
my ($client_root, $cfg_file) = @_;
my $dir = path($client_root)->realpath;
while (1) {
# say "Looking at $dir";
if ($dir->child($cfg_file)->exists) {
return $dir;
} elsif ($dir->is_rootdir) {
return undef;
} else {
$dir = $dir->parent;
}
}
}
my $cfg = '.cfg';
my $dir = '/user/home/wkspace/abc/def/MAIN';
say get_p4_config_updir($dir, $cfg) // "File not found";
或者類似于@rajashekar 通過使用chdir獲取每個目錄的父目錄來遍歷目錄樹的想法的版本。這個使用File::chdir,它可以讓您local調整對當前作業目錄的更改(并在函式/范圍退出時恢復原始目錄),并提供當前目錄及其可以操作的父目錄的方便陣列視圖:
use File::chdir;
...
sub get_p4_config_updir {
my ($client_root, $cfg_file) = @_;
local $CWD = $client_root; # Magic happens here
while (1) {
# say "Looking at $CWD";
if (-e $cfg_file) {
return $CWD;
} elsif ($CWD eq "/") {
return undef;
} else {
pop @CWD; # CDs to the next parent directory
}
}
}
uj5u.com熱心網友回復:
您可以使用核心庫以獨立于平臺、可讀的方式執行此操作,而無需cwd在其余代碼中使用并可能導致遠距離操作影響:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Spec::Functions qw(catfile rel2abs updir);
sub get_p4_config_updir
{
my ($dir, $file) = @_;
$dir = rel2abs($dir);
do {
my $path = catfile $dir => $file;
return $dir if -e $path;
return if $dir eq (my $new_dir = rel2abs(catfile $dir, updir));
$dir = $new_dir;
} while ('NOT_DONE');
return;
}
sub main {
my ($cfg, $dir) = @_;
my $path = get_p4_config_updir($dir, $cfg);
if (defined $path) {
printf("Found '%s' in '%s'\n", $cfg, $path);
}
else {
printf(
"Did not find '%s' in '%s' or any of its parent directories\n",
$cfg,
$dir,
);
}
}
main(@ARGV);
輸出:
C:\Users\u\AppData\Local\Temp> perl p.pl linux.bin .
Found 'linux.bin' in 'C:\'
uj5u.com熱心網友回復:
為什么要處理路徑名,當您可以用 遍歷目錄結構時..?
- 如果檔案存在于當前目錄中,則回傳它。
- 否則上升
..并重復該程序。
use Cwd qw(cwd);
sub search_up {
my ($dir, $file) = @_;
chdir($dir);
while (1) {
if (-e $file) {
print "$file exists in $dir\n";
return $dir;
} elsif ($dir eq "/") {
return;
} else {
chdir("..");
$dir = cwd;
}
};
}
uj5u.com熱心網友回復:
請查看以下代碼片段是否符合您的要求。
該腳本正在向檔案系統的根目錄查找組態檔,找到的檔案名存盤在一個陣列中@found。
use strict;
use warnings;
use feature 'say';
my $dir = '/user/home/wkspace/abc/def/MAIN';
my $ext = 'cfg';
my($cwd,@found);
for( split('/',$dir) ) {
$cwd .= "$_/";
push @found, glob( $cwd . "*\.$ext" );
}
if( @found ) {
say for @found;
} else {
say 'No file(s) was found';
}
exit 0;
以下代碼片段正在尋找遠離根檔案系統的組態檔,從$dir.
如果找到任何檔案,則它們將存盤在陣列參考下$found,然后在終端上列印出來。
如果未找到任何檔案,您將收到一條訊息通知。
use strict;
use warnings;
use feature 'say';
my $dir = '/user/home/wkspace/abc/def/MAIN';
my $ext = 'cfg';
my $found = find($dir,$ext);
if( $found ) {
say for @$found;
} else {
say 'No file(s) was found';
}
exit 0;
sub find {
my $dir = shift;
my $ext = shift;
my $ret;
for( glob("$dir/*") ) {
push @$ret, $_ if /\.$ext\z/;
if( -d ) {
my $found = find($_,$ext);
push @$ret, @$found if $found;
}
}
return $ret;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/329714.html
標籤:perl
