2 macos perl whitespace find backticks
我有一个搜索,从我的角度来看,使用反引号是解决这个问题的唯一方法.我正在尝试mdls从Perl中调用目录中每个文件的命令,以找到它上次访问的时间.我遇到的问题是,在我的文件名中,find我有非转义空格,bash显然不喜欢.有没有一种简单的方法可以在传递文件名之前转义文件名中的所有空格mdls.如果这是一个明显的问题,请原谅我.我对Perl很新.
my $top_dir = '/Volumes/hydrogen/FLAC';
sub wanted { # Learn about sub routines
if ($File::Find::name) {
my $curr_file_path = $File::Find::name. "\n";
`mdls $curr_file_path`;
print $_;
}
}
find(\&wanted, $top_dir);
Run Code Online (Sandbox Code Playgroud)
如果您只想在操作系统上次访问时间方面"最后访问时间",那么这mdls是错误的工具.使用perl的stat.如果您想要根据Mac注册的应用程序(即Quicktime或iTunes的歌曲)的最后访问时间,那么mdls可能是正确的工具.(你也可以使用osascript直接查询Mac应用程序...)
反引号用于捕获文本返回.由于您使用MDLS,我想捕捉和解析文本的还是要来.
所以有几种方法:
使用系统的列表形式,并且不需要引用(如果您不关心返回文本);
在发送到sh之前,使用String :: ShellQuote转义文件名;
构建字符串并在发送到shell之前用单引号括起来.这比听起来更难,因为带单引号的文件名称会使你的报价失败!例如,sam's song.mp4是一个合法的文件名,但如果你用单引号括起来,那么你得到'sam's song.mp4'的不是你的意思......
使用open打开一个管道,这样子进程的输出:open my $fh, '-|', "mdls", "$curr_file" or die "$!";
String :: ShellQuote的示例:
use strict; use warnings;
use String::ShellQuote;
use File::Find;
my $top_dir = '/Users/andrew/music/iTunes/iTunes Music/Music';
sub wanted {
if ($File::Find::name) {
my $curr_file = "$File::Find::name";
my $rtr;
return if -d;
my $exec="mdls ".shell_quote($curr_file);
$rtr=`$exec`;
print "$rtr\n\n";
}
}
find(\&wanted, $top_dir);
Run Code Online (Sandbox Code Playgroud)
管道示例:
use strict; use warnings;
use String::ShellQuote;
use File::Find;
my $top_dir = '/Users/andrew/music/iTunes/iTunes Music/Music';
sub wanted {
if ($File::Find::name) {
my $curr_file = "$File::Find::name";
my $rtr;
return if -d;
open my $fh, '-|', "mdls", "$curr_file" or die "$!";
{ local $/; $rtr=<$fh>; }
close $fh or die "$!";
print "$rtr\n\n";
}
}
find(\&wanted, $top_dir);
Run Code Online (Sandbox Code Playgroud)