循环查找命令的输出

时间:2012-11-15 16:48:55

标签: perl

我想在Perl中发出find命令并循环生成文件路径。我正在尝试(但没有运气):

my $cmd;

open($cmd, '-|', 'find $input_dir -name "*.fastq.gz" -print') or die $!;

while ($line = <$cmd>) {
   print $line;
}

close $cmd;

有什么想法吗?

由于

4 个答案:

答案 0 :(得分:3)

您没有对*字符应用足够的转义。 预先\应该修复它。

最好不要首先调用shell, 通过分离参数:

use warnings;
use strict;

open(my $cmd, '-|', 'find', $input_dir, '-name' ,'*.fastq.gz', '-print') or die $!;

while (my $line = <$cmd>) {
   print $line;
}

close $cmd;

答案 1 :(得分:3)

您的问题似乎是使用单引号。您的变量不会被插值,但变量名称将按原样输入find

但为什么不使用File::Find

> perl -MFile::Find -lwe '
    $foo = "perl"; 
    find ( sub { /\.pl$/i or return; print $File::Find::name }, $foo);'
perl/foo.pl
perl/parsewords.pl
perl/yada.pl

这里,wanted子例程只是与文件名匹配的模式。除非扩展名为.pl,否则我们退出(返回)子例程,否则我们使用相对路径打印文件名。

答案 2 :(得分:2)

如果你要做

print 'find $input_dir -name "*.fastq.gz" -print';

问题应该变得明显:单引号不插入。你可能打算做

open(my $cmd_fh, '-|', qq{find $input_dir -name "*.fastq.gz" -print}) or die $!;

但那也是错误的。您不会将$input_dir转换为shell文字。有两种解决方案。

use String::ShellQuote qw( shell_quote );

my $cmd = shell_quote("find", $input_dir, "-name", "*.fastq.gz", "-print");
open(my $cmd_fh, '-|', $cmd) or die $!;

或者

my @cmd = ("find", $input_dir, "-name", "*.fastq.gz", "-print");
open(my $cmd_fh, '-|', @cmd) or die $!;

答案 3 :(得分:2)

要阅读命令的输出,请使用backtick operator

my $command = "find $inputdir ...";  # interpolate the input directory
my $output  = `$command`;            # be careful here
my @lines   = split /\n/ => $output; # split in single lines

for my $line (@lines) {              # iterate
    # do something with $line
}

我认为它比滚边更好阅读。缺点是它会阻塞,所以如果你想处理大量输出的大量输出字符串,那么管道方法可能会更好。

但您可能想要使用适当的模块。 File::Find(核心模块)应该符合您的需求。