我想从目录中加载所有图片并将它们保存到数组中。
@files = `ls $ARGV[0] | grep -i -E jpe?g|gif|png$`;
这一行给出了一个错误:Final $ should be \$ or $name
@files = `ls $ARGV[0] | grep -i -E \'jpe?g|gif|png$\'`;
此行有效,但它也会加载图片“img.jpg.bmp”而我不是我想要的,甚至加载目录,这是次要但也很糟糕。我做错了什么?
答案 0 :(得分:2)
您还可以使用glob功能获取文件列表,并使用grep对其进行过滤。 e.g:
my(@files) = grep { /\.(?:jpe?g|gif|png)\z/ } glob '"*"';
或简单地说:
my(@files) = glob '"*.jpeg" "*.jpg" "*.gif" "*.png"';
答案 1 :(得分:0)
使用shell读取目录或grep
是一种悲伤
use autodie;
opendir my $dir, $ARGV[0];
my @files = grep !/\A\.\.?\z/ && /\.(?:jpe?g|gif|png)\z/, readdir $dir;
closedir $dir;
(我们必须手动过滤掉当前目录.
和父目录..
。\A
就像^
而\z
有点像{ {1}},但始终在字符串末尾匹配)
$
的问题在于它具有双引号字符串的插值语义。 `command`
始终表示下一个单词或字符是变量名称(正则表达式除外)。 $
将是prematch variabele,但Perl足够聪明,可以看到你不想要它。您的错误消息建议的解决方案是转发$`
:
$
使用单引号进行环绕仅对shell级别有用,而不是在出现错误消息的Perl级别上。
在正则表达式中,行结束断言`grep -i -E jpe?g|gif|png\$` # … and it meant this.
# It still thinks gif and png are commands
`grep -i -E '(jpe?g|gif|png)\$'` # regex correctly quoted on shell level
只是一个普通的原子,如$
或p
。与[abc]
或()
或|
不同,它不是运营商。因此,您必须强制使用parens正确的优先级。请参阅我提出的Perl解决方案中的正则表达式,如上所述。