我正在学习编码,按照教程尝试解决一个烦人的问题 - 清理macOS上的文件,这样它们就不会干扰OneDrive工作。
我已经遵循了几个教程,它几乎达到了我所希望的效果。
#!/usr/bin/perl -w
use strict;
use warnings;
use File::Find;
my @argv;
my $dir = $ARGV[0];
find(&dirRecurs, $dir);
sub dirRecurs{
if (-f and not 's/^./' )
{
(my $txt = $_) =~ s/^ | (?=.)|[/!#%^?*&()\]| $//g;
rename($_, $txt);
}
}
我希望它会因为and not 's/^./'
而将.dotfiles
从重命名过程中排除,但事实并非如此。 如果我从 if 行中删除and not 's/^./'
,一切都像我希望的那样工作,除了
我希望正则表达式中的/
像more/less.pdf
一样重命名文件,但它没有
有问题的代码行是:
if (-f and not 's/^./' )
- 当
-f
为真而's/^./'
为假时,此操作成功-f
测试$_
是否为文件- 在布尔上下文中,
's/^./'
测试给定字符串是否不为 null
显然,任何包含某些字符的字符串都不是空的,因此if
测试总是失败。
查看字符串的内容,很明显,意图是插入正则表达式测试。所需的是m//
形式("匹配")。已经(几乎)提供的那个是s///
(搜索和替换)的格式错误版本。
在 Perl 中,正则表达式通常不显示为字符串。适当的形式是(m
是可选的):
if (-f and not m/^./)
作为旁白:
@argv
未在代码中使用(并且与@ARGV
不同)- 使用
find(&dirRecurs, @ARGV);
搜索多个路径(作为 Perl 脚本的参数提供) - 即使没有更改,也可以执行重命名。这可以通过包装和
if
来防止:
if ((my $txt = $_) =~ s/^ | (?=.)|[/!#%^?*&()\]| $//g) {
rename($_, $txt);
}
# or:
rename($_, $txt)
if (my $txt = $_) =~ s/^ | (?=.)|[/!#%^?*&()\]| $//g;