英文:
perl glob files in directory
问题
我正在使用glob来读取某个目录中存在的*_file.log
文件,但下面的代码似乎不起作用。
示例路径中有以下几个文件:
/user/home/xpath/logs/
abc_file.log
def_file.log
x.txt
代码:
my $home = "/user/home";
if (glob ("${home}/xpath/logs/*_file.log")){
print "工作\n";
}
else {
print "有些问题\n";
}
英文:
I am using glob to read *_file.log
exist in certain directory but below code seems not working.
Example path having these few files:
/user/home/xpath/logs/
abc_file.log
def_file.log
x.txt
Code:
my $home = "/user/home";
if (glob ("${home}/xpath/logs/\*_file.log")){
print "work\n";
}
else {
print "something wrong\n"
}
答案1
得分: 2
如已解释,需要检索来自glob的所有匹配项。鉴于glob
是一个具有很长记忆的“非常全球”的东西,最好在列表上下文中使用它,以立即耗尽其返回,并进行调查。执行问题尝试的一种方法如下:
if ( my @entries = glob "$home/xpath/logs/*_file.log" ) {
print "file: $_\n" for @entries;
}
else {
print "未找到此类条目\n";
}
我清理了一些不必要的语法元素。
一些建议:
-
如果您真的要使用主目录,环境变量可以在%ENV哈希中使用,如
$ENV{HOME}
(或参见File::HomeDir) -
feature say会在打印输出中添加换行符,使其更加美观。例如,我们可以这样写:
say for @files;
需要通过
use feature qw(say);
启用,或者通过use
Perl 版本5.10或更新版本,或者通过use
一些启用它的包/框架 -
一旦您使用
glob
,还可以查看File::Glob,它提供了一个良好处理名称中的空格的可替代方法。
英文:
As explained, all matches from the glob need be retrieved. Given that glob
is a "very" global creature with long memory better use it in list context to exhaust its return right away, and then investigate it. One way to do what the question tries
if ( my @entries = glob "$home/xpath/logs/*_file.log" ) {
print "file: $_\n" for @entries;
}
else {
print "No such entries found\n"
}
I cleaned up some of unneeded syntax elements.
A few comments
-
If you really mean to use the home directory, the environment variable is available in the %ENV hash, as
$ENV{HOME}
(or see File::HomeDir) -
The feature say adds a newline to prints making them far nicer. For example, we can say
say for @files;
It need be enabled by
use feature qw(say);
, or byuse
-ing a Perl version 5.10 or newer, or byuse
-ing some of a number of packages/frameworks that enable it -
Once you reach for
glob
also have a look at File::Glob, which provides a drop-in replacement that handles spaces in names nicely.
答案2
得分: 1
使用 `if glob` 是错误的。
```none
$ ls
a.log
b.log
$ perl -Mv5.14 -e'
sub test { say "$_[0]: ", glob( $_[0] ) ? "至少有一个匹配" : "没有匹配" }
test( "*.log" );
test( "*.txt" );
test( "*.log" );
'
*.log: 至少有一个匹配 # 正确
*.txt: 至少有一个匹配 # 错误
*.log: 没有匹配 # 错误且矛盾
glob
在标量上下文中充当迭代器。
- 第一次调用时,它返回第一个匹配项。
- 第二次调用时,它返回第二个匹配项(不管参数如何)。
- 当在返回所有结果后调用时,它返回
undef
。
如果你要使用 glob
,你需要获取所有结果,而不仅仅是第一个。
例如,以下使用 scalar( () = ... )
技巧 在列表上下文中调用 glob
(获取所有结果)并计算其返回的项目数。
$ perl -Mv5.14 -e'
sub test { say "$_[0]: ", ( () = glob( $_[0] ) ) ? "至少有一个匹配" : "没有匹配" }
test( "*.log" );
test( "*.txt" );
test( "*.log" );
'
*.log: 至少有一个匹配
*.txt: 没有匹配
*.log: 至少有一个匹配
英文:
Using if glob
is wrong.
$ ls
a.log
b.log
$ perl -Mv5.14 -e'
sub test { say "$_[0]: ", glob( $_[0] ) ? "at least one match" : "no matches" }
test( "*.log" );
test( "*.txt" );
test( "*.log" );
'
*.log: at least one match # Correct
*.txt: at least one match # Incorrect
*.log: no matches # Incorrect and a contradiction
glob
in scalar context acts as an iterator.
- The first time it's called, it returns the first match.
- The second time it's called, it returns the second match (regardless of the argument).
- When it's called after all results have been returned, it returns
undef
.
If you're going to use glob
, you're going to have to get all the results, not just the first.
For example, the following uses the scalar( () = ... )
trick to call glob
in list context (getting all the results) and count the number of items it returns.
$ perl -Mv5.14 -e'
sub test { say "$_[0]: ", ( () = glob( $_[0] ) ) ? "at least one match" : "no matches" }
test( "*.log" );
test( "*.txt" );
test( "*.log" );
'
*.log: at least one match
*.txt: no matches
*.log: at least one match
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论