递归子目录grep

时间:2016-05-11 16:15:38

标签: perl grep

抱歉感到痛苦。

我正在尝试从2,000多个子目录中的每个Distance:文件中grep字符串pairsAngles.txt;子目录的名称是从CSV文件中获取的。

每个子目录包含一个pairsAngles.txt,其中只有一行包含Distance:。但是,我当前的foreachwhile循环为每个子目录提供了8个Distance值。

此外,每个后续子目录都会获得与先前子目录的所有距离。

像这样:

enter image description here

图片的文字版本(第4行,第2列有4 * 8 = 32条距离)

所有pairsAngles.txt个文件都在子目录中,每个子目录都有一个唯一的名称。

我首先从CSV文件中读取所有子目录名称并将它们拆分成一个数组,然后从该数组中检索每个元素以进入一个子目录,以便我可以grep。

clst1.csv只有一列,即子文件夹名称:

oligomerAngle-1h2s-000_001-0003_0025_A-0034_0056_A-B004A012
oligomerAngle-5ax0-000_001-0010_0036_A-0042_0064_A-B004A013
oligomerAngle-4qnd-004_005-0046_0065_A-0069_0091_A-A004B006
oligomerAngle-2j8c-003_004-0171_0196_L-0226_0250_L-B011A001
oligomerAngle-2j8c-003_004-0171_0196_L-0226_0250_L-B011A001

Distance: 7.98675 
Distance: 7.98675 
Distance: 7.98675 
Distance: 7.98675 
Distance: 7.98675 
Distance: 7.98675 
Distance: 7.98675 
Distance: 7.98675
Distance: 7.95099 
Distance: 7.95099 
Distance: 7.95099 
Distance: 7.95099 
Distance: 7.95099 
Distance: 7.95099 
Distance: 7.95099
Distance: 7.95099
Distance: 7.87554 
Distance: 7.87554 
Distance: 7.87554 
Distance: 7.87554 
Distance: 7.87554 
Distance: 7.87554
Distance: 7.87554 
Distance: 7.87554 
Distance: 7.69417 
Distance: 7.69417 
Distance: 7.69417 
Distance: 7.69417 
Distance: 7.69417
Distance: 7.69417 
Distance: 7.69417 
Distance: 7.69417

但实际值应为“距离:7.69417” 不知道出了什么问题。这是代码:

use File::Find;
use Text::CSV_XS;

my @pairs  = ();
my @result = ();
my $in;
my $out;
my $c1;
my $dist = "";
my $dir  = "/home/oligomerAngle";

my $cluster = "clst1.csv";
open( $in, $cluster ) || die "cannot open \"$cluster\": $!";

my $cU = "clst1Updated.csv";
open( $out, ">$cU" ) || die "cannot open '$cU' $!";

my $csv = Text::CSV_XS->new( { binary => 1, auto_diag => 1, eol => $/ } );

while ( $c1 = <$in> ) {
    chomp $c1;
    @pairs = split( ' ', $c1 );

    foreach my $pair (@pairs) {

        find( \&Matches, "$dir/$c1" );

        sub Matches {
            open( my $subdir, "pairsAngles.txt" ) or die "$!";

            while ( $dist = <$subdir> ) {

                if ( $dist =~ m/Distance:/ ) {
                    push( @result, "$dist" );
                }
            }
        }

        chdir "..";
        $csv->say( $out, [ "@pairs", "@result" ] );
    }
}

if ( not $csv->eof ) {
    $csv->error_diag();
}

close $out or die "$!";

2 个答案:

答案 0 :(得分:1)

鉴于澄清,发布的代码似乎极大地使问题过于复杂。

下面的代码从$cluster迭代的<$in>文件中获取子目录名称,然后使用$dir构建文件名。然后迭代文件中的行以找到具有该模式的行。一旦发生这种情况,我们打印结果并转到下一个文件(在下一个子目录中)。

请注意,除非稍后进行更多处理,否则我们确实不需要@result

# Iterate over subdirectories that each have the file
while ( $c1 = <$in> ) {
    chomp $c1;

    # Build the full file name in this subdirectory, open the file
    my $filename = "$dir/$c1/pairsAngles.txt";
    open my $fh_in, $filename  or die "$!";

    # Iterate over lines in the file to find the pattern
    while ( my $line = <$fh_in> ) { 
        if ( $line =~ m/Distance:/ ) { 
            # Found our result, print output
            chomp($line);
            $csv->say($out, [$c1, $line]);
            push @result, $line;
            # No need to continue if we know there is exactly one
            last; 
        }   
    }   
}
# Do something else with @result if needed ...

答案 1 :(得分:0)

  • 您的数据结构有点奇怪。它们不是命名具有有意义名称的文件,而是命名为相同并隐藏在子目录中。为什么.csv中列出了目录,你应该跳过一些目录吗?您是否考虑过使用数据库?

  • 将子组件移出循环

  • 你在“$ dir / $ c1”上执行find(),其中$ c1是你可以用空格分割()的东西。这可能就是你重复的原因。尝试

    打印“$ dir / $ c1 \ n”中的下一个发现

在调用find()之前,你会看到会发生什么。

  • 我无法理解你想做什么,阅读这些代码使我在这个意义上并不明智。你确定自己知道吗?首先尝试想要做什么,而不是 你是怎么做的。

会像

grep -r Distance directory

办?