远程目录mydir
的内容:
blah.myname.1.txt
blah.myname.somethingelse.txt
blah.myname.randomcharacters.txt
blah.notmyname.1.txt
blah.notmyname.2.txt
...
在perl中,我想用myname
我通过适当的引用很难真的。请帮忙。
代码失败
my @files;
@files = $ftp->ls( '*.myname.*.txt' ); # finds nothing
@files = $ftp->ls( '.*.myname.*.txt' ); # finds nothing
等。
如何将通配符放在ls
中,而不是由perl解释?这里出了什么问题?
答案 0 :(得分:6)
我将假设您正在使用Net::FTP
包。然后这部分文档很有趣:
ls ( [ DIR ] )
获取DIR或当前目录的目录列表。
在数组上下文中,返回从服务器返回的行列表。在标量上下文中,返回对列表的引用。
这意味着如果您在没有参数的情况下调用此方法,则会从当前目录中获取所有文件的列表,否则从指定的目录中获取。
没有关于任何模式的消息,这并不令人惊讶:FTP只是一个传输文件的协议,而这个模块只是该协议的包装。
您可以使用grep
轻松完成过滤:
my @interesting = grep /pattern/, $ftp->ls();
要选择包含字符序列myname
的所有文件,请使用grep /myname/, LIST
要选择包含字符序列.myname.
的所有文件,请使用grep /\.myname\./, LIST
要选择以字符序列.txt
结尾的所有文件,请使用grep /\.txt$/, LIST
。
LIST
是$ftp->ls
或其他grep,因此您可以轻松链接多个过滤步骤。
当然,Perl Regexes比这更强大,我们可以在一个/\.myname\.[^.]+\.txt$/
或其他内容中进行所有过滤,具体取决于您的确切要求。如果你迫切需要一个全局语法,可以使用工具将glob模式转换为regex对象,比如Text::Glob
,甚至可以直接进行全局匹配:
use Text::Glob qw(match_glob);
my @interesting = match_glob ".*.myname.*.txt", $ftp->ls;
然而,至少可以说,这是不优雅的,因为正则表达式远更强大且绝对值得学习。