Sco*_*ott 3 perl glob string-interpolation
我有两个目录,每个目录都有一个文件:
$ ls -l "test dir["
-rw-r--r-- 1 root media 0B 11 Dec 16:53 .ignoreme
Run Code Online (Sandbox Code Playgroud)
和
$ ls -l "test [dir]"
-rw-r--r-- 1 root media 0B 11 Dec 16:34 .ignoreme
Run Code Online (Sandbox Code Playgroud)
我正在使用 Perl 来测试“.ignoreme”文件是否存在:
$ perl -e '$d="test dir["; print -e glob qq("$d"/.ignore*); print "\n";'
1
Run Code Online (Sandbox Code Playgroud)
哪个有效,以及
$ perl -e '$d="test [dir]"; print -e glob qq("$d"/.ignore*); print "\n";'
Run Code Online (Sandbox Code Playgroud)
哪个没有。
我猜这与这[]对有关,但我不确定相互作用。有人可以请教我。我也很感谢修复以匹配任何$d包含[].
在glob解释对[]作为元字符一个字符类。†这很容易通过一个简单的实验得到证实
mkdir zZ
touch zZ/f.txt
perl -wE'say for glob qq([az][bZ]/*)'
Run Code Online (Sandbox Code Playgroud)
这正确地列出了文件。
然后在问题的第二种情况下,glob根本不查找[]名称中带有文字的目录,而是查找名称中带有任一d,i,r字符的目录test␣。
一种解决方法是使用\Q...\E(参见quotemeta)来逃避那些[]
say for glob qq(\Q$d\E/.ignore*);
Run Code Online (Sandbox Code Playgroud)
这也可以根据需要转义空格——但是它也会转义其他内容,因此您不能对序列内的内容使用通配符(对于一个)。这不应该是一个问题,因为目录名称不会包含用作通配符的字符,但最好记住它。
另一种选择是在形成目录名称变量时转义特殊字符
perl -wE'$d = quotemeta "test [dir]"; say for glob qq($d/*)'
Run Code Online (Sandbox Code Playgroud)
现在照常工作。
不需要双引号,因为quotemeta它也会处理空格。
† 的水珠页说:
该运算符是使用标准
File::Glob扩展实现的。
和File::Glob文档专门[]列为元字符,用于字符类。