在不使用任何 Perl 模块的情况下,是否可以在 Perl 中只用几行代码来执行以下操作?
find . -type f | xargs grep -l "2000.*Created" | cut -c3-100
上面只给了我包含“2000.*Created”的文件的文件名。我想在 Perl 中执行此操作并将结果推送到一个数组(文件名数组)中。
我发现 Perl File::Finder 模块具有类似的功能,但在我当前的工作环境中,我无法访问或下载任何模块。
这可以用一两行代码完成吗?
在不使用任何 Perl 模块的情况下,是否可以在 Perl 中只用几行代码来执行以下操作?
find . -type f | xargs grep -l "2000.*Created" | cut -c3-100
上面只给了我包含“2000.*Created”的文件的文件名。我想在 Perl 中执行此操作并将结果推送到一个数组(文件名数组)中。
我发现 Perl File::Finder 模块具有类似的功能,但在我当前的工作环境中,我无法访问或下载任何模块。
这可以用一两行代码完成吗?
当然这是可能的。
perl -MFile::Find -lwe '
find(sub { -f && push @ARGV, $File::Find::name }, '.');
while(<>) { if (/2000.*Created/) { print substr($ARGV,2); close ARGV; } }'
File::Find是一个核心模块,所以它应该已经在你的系统上。该find子例程将找到所有常规文件并将它们推送到@ARGV,以便我们可以使用菱形运算符读取它们。然后我们循环使用您的正则表达式检查内容的文件。如果找到,我们打印不带前 2 个字符的文件名(我假设它相当于cut -c3-100)。close ARGV线路短路以防止多次匹配。
我更喜欢 File::Find 这个例子——它更便携,而且 File::Find 可以做一些非常漂亮的事情。但是,我将提到一种方法,它可以在没有内置支持的情况下对其他命令有用。
open F,'find . -type f | xargs grep -l "2000.*Created" | cut -c3-100 |' || die 'cannot execute';
while(<F>) { chomp ; push(@a,$_)}
注意打开的尾随管道 ( |) ... 这很重要,因为 Perl 会自动为您完成所有连接管道的工作。
这也可以使用较新的 3 参数 open 来编写:
open my $fh, '-|', 'find . -type f | xargs grep -l "2000.*Created" | cut -c3-100' || die 'cannot execute';
while(<$fh>) { chomp ; push(@a,$_)}
作为旁注,find | xargs如果您的文件名带有空格,将会遇到一些问题。您可以通过-print0操作 onfind和-0标记 on来解决这个问题xargs:
find . -type f -print0 | xargs -0 -l "2000.*Created" | cut -c3-100