这个Perl如何检查一个目录是否为空工作?

时间:2009-07-14 15:38:51

标签: perl glob

我今天得到了这个奇怪的代码行,它告诉我'空'或'非空'取决于CWD中是否有任何项目(...除外)。< / p>

我想知道它是如何工作的,因为它对我没用。

perl -le 'print+(q=not =)[2==(()=<.* *>)].empty'

我感兴趣的是<.* *>。我不明白它如何获取目录中所有文件的名称。

5 个答案:

答案 0 :(得分:16)

这是一个高尔夫单线。 -e标志表示执行命令行的其余部分作为程序。 -l启用自动行结束处理。

<.* *>部分是一个包含两个要扩展的模式的glob:.**

这部分

(q=not =)

是包含单个值的列表 - 字符串“not”。 q=...=是一个替代的字符串分隔符,显然是使用的,因为单引号用于引用单行。

[...]部分是该列表的下标。下标的值将为0(值“not”)或1(nothing,打印为空字符串),具体取决于此比较的结果:

2 == (()=<.* *>)

这里发生了很多事情。比较测试glob是否返回了恰好两个项目(假设为...)的列表,但它是如何做到这一点很棘手。内括号表示空列表。分配给此列表会将glob置于列表上下文中,以便返回目录中的所有文件。 (在标量上下文中,它的行为类似于迭代器,并且一次只返回一个。)赋值本身在标量上下文中进行计算(位于比较的右侧),因此返回分配的元素数。

前导+是为了防止Perl将列表解析为print的参数。尾随.empty将字符串“empty”连接到列表中的任何内容(即“not”或空字符串)。

答案 1 :(得分:7)

<.* *>

是由两种模式组成的glob:.*是以.开头的所有文件名,*对应于所有文件(这与通常的DOS / Windows约定不同) 。

(()=<.* *>)

评估列表上下文中的glob,返回匹配的所有文件名。

然后,与2的比较将其置于标量上下文中,因此将2与返回的文件数进行比较。如果该数字为2,则唯一的目录条目为...,句点。 ; - )

答案 2 :(得分:3)

<.* *>表示(glob(".*"), glob("*"))glob以与shell相同的方式扩展文件模式。

答案 3 :(得分:2)

我发现B::Deparse模块有助于破译一些抛弃大多数程序员眼睛的东西,例如q=...=构造:

$ perl -MO=Deparse,-p,-q,-sC 2>/dev/null << EOF
> print+(q=not =)[2==(()=<.* *>)].empty
> EOF
use File::Glob ();
print((('not ')[(2 == (() = glob('.* *')))] . 'empty'));

当然,这不会立即产生“可读”的代码,但肯定能转换出一些绊脚石。

答案 4 :(得分:0)

该功能的文档为here。 (在该部分末尾滚动)