用于在目录中的每个目录上运行Perl脚本的Shell脚本

时间:2015-02-03 19:52:49

标签: perl shell loops directory

设置:

包含一年中每一天的目录的数据目录。即data / 2014-01-01 /至2014-12-31。我有一个perl脚本,我在每个日期目录中单独运行。

我正在尝试运行一个shell脚本来运行数据,并从2014-02-15到2014-07-20遍历每个目录,并在每个目录中运行perl脚本。 perl脚本大约需要20秒才能运行。这是我到目前为止,它只会在2月份运行,并且不会等待perl脚本完成。我希望它在范围内的每个目录上运行,并在重新循环之前等待循环内的perl脚本完成。

 #!/bin/bash

 folders=`find 2014-02*`

 for folder in $folders; do 
 cd $folder
 perl C:/Tools/script.pl
 cd ..
 done

1 个答案:

答案 0 :(得分:3)

为什么不在perl中全部完成?它具有File::Find内置模块的完美良好的遍历功能。

封装您的脚本'作为子程序。

#!/usr/bin/perl

use strict;
use warnings;
use File::Find;

sub your_script_sub {
    my ( $dir ) = @_;
    #do something with $dir. At a worst case, you could just run your script.
    #but there's no real reason to do that, as it's perl already. 
}

sub run_script_in_dirs {
   if ( -d $File::Find::name ) { 
        your_script_sub($File::Find::name);
    }
}

find ( \&run_script_in_dirs, "/path/to/your/dir" );

对于奖励积分 - 您可以使用线程来并行化目录中的运行脚本:

#!/usr/bin/perl
use strict;
use warnings;
use threads;
use Thread::Queue;

my $num_threads = 4;
my $dir_q = Thread::Queue -> new(); 

sub your_script_sub {
   while ( my $dir = $dir_q -> dequeue() ) {
          # do something in $dir;
   }
}

sub find_dirs_to_run_script {
   if ( -d $File::Find::name ) { 
        $dir_q -> enqueue($File::Find::Name);
    }
}

for ( 1..$num_threads ) {
   threads -> create ( \&your_script_sub );
}

find ( \&find_dirs_to_run_script, "/path/to/dirs" );

$dir_q -> end();

foreach my $thr ( threads -> list() ) { $thr -> join() }