使用 Perl 列出数据文件中但目录列表中缺少的文件的一种简单方法是在目录中使用文件测试 (或传递完整路径),该文件会打印文件名“如果文件不存在”或“除非文件存在”:
perl -nE 'map { say if !-e $_ } m/\"(.*)\"/ if /filename/' data.js
或 做相反的事情(你的例子) - ie 如果在目录列表中找不到文件名($fname)从您的文件列表数据 (data.js) 创建的名称数组 (@m):
perl -nE 'push @m, m/\"(.*)\"/ if /filename/ }{
for $fname (glob "*"){ say $fname if !grep { $_ eq $fname } @m}' data.js
这是@neuhaus 发布的完整脚本变体。不同之处在于以下方法使用IO::All 从目录'./images/' 创建一个IO“对象”作为哈希,然后列出带有keys 的文件的名称。我修改了您的文本文件中的数据来说明grep unless 语句:
# files.pl
use IO::All;
@files = keys %{ io('./images/') } ;
while(<DATA>) {
push @flist, m/\"(.*)\"/ if /filename/ ;
}
for $fname ( @flist) {print $fname unless grep { $_ eq $name } @files} ;
__DATA__
{
name: "A",
filename: "a.png"
},
{
name: "X",
filename: "x.png"
},
{
name: "Z",
filename: "z.png"
}
输出(如果perl files.pl 在包含./images/ 目录的目录中运行):
% ls ./images/
a.png x.png y.png z.png
% perl files.pl
y.png
在__DATA__ 部分(代表data.js 文件)中,文件名被提取到@files。目录列表中的文件打印为unless,可以在@files 中使用grep 找到它们。
这是一个与data.js 中的数据相结合的版本:
perl -MIO::All -lne 'push @flist, m/\"(.*)\"/ if /filename/ ;
}{ for $name (keys %{ io "./images/" }){ print $name
unless grep { $_ eq $name } @flist }' data.js
更接近 Unix 的方法可能会在 /images/ 目录中使用 glob(警告:在某些平台上有时会出现与带有空格的文件名有关的问题):
perl -MIO::All -lne 'push @flist, m/\"(.*)\"/ if /filename/ ;
}{ for $name ( glob("*.png") ){ print $name
unless grep { $_ eq $name } @flist }' data.js
或open 和opendir 的文件和目录句柄
...
opendir(my $dir, ".") || die;
@files = readdir $dir ;
...