2017-08-15 32 views
-2

我修改了一个现有的perl脚本,该脚本通过转到他们的目录并解析pass,fail或incomplete来检查某些测试的状态。我想这个脚本扩展生成包含基于3串的未完成的测试子表:使用grep通过perl查找不同目录中的文件中的匹配模式

"Error: Failure to checkout svverification license feature." 
"Error: Unable to checkout verification license - required for testbench features" 
"FATAL ERROR: License connection lost and unable to reconnect after multiple attempts." 

每个测试的名字都有自己的目录,该目录内是一个名为vsim.log日志文件。我可以用grep做这个目录,但是我认为将它实现到脚本中会很好,所以每次有不完整的时候我都不必手动grep

该脚本有一个变量$cur_test_name,我将用它来执行此操作,因为我必须确保进入正确的子目录。

chdir("/testout/$cur_test_name.1/") or die "Cannot chdir to /testout/$cur_test_name.t"; 
if(system(grep -f "Error: Failure to checkout svverification license feature." vsim.log) or 
system(grep -f "Error: Unable to checkout verification license - required for testbench features" vsim.log) or 
system(grep -f "# FATAL ERROR: License connection lost and unable to reconnect after multiple attempts." vsim.log)) 
{ 
    open($incomplete_tests, '>'; 'incompletes.lst') or die "Cannot open file $!in write mode"; 
    print {$incomplete_tests} $cur_Test_name . "\n";  
    close $incomplete_tests; 
} 
chdir("../../") or die "Cannot chdir to ../../"; 

所以基本上,我想改变目录到子目录,并检查vsim.log文件中存在这些模式。如果他们通过open创建一个新文件(我认为这是如何完成的),并将测试名称变量写入文件。然后关闭文件,然后返回顶层目录,对每个不完整的测试重复此操作。

但是这不能编译和Im新的perl,所以我很难找出如何正确使用system()。我已经看到了不同的格式,我见过一些解决方案,只使用grep而没有system,所以我被卡住了。

我得到的错误有以下几种:

Bareword found where operator expected at bin/run_regress.pl line 1279, near ""Error: Failure to checkout svverification license feature." vsim" 
     (Missing operator before vsim?) 
Bareword found where operator expected at bin/run_regress.pl line 1279, near ""Error: Unable to checkout verification license - required for testbench features" vsim" 
     (Missing operator before vsim?) 
Bareword found where operator expected at bin/run_regress.pl line 1279, near ""# FATAL ERROR: License connection lost and unable to reconnect after multiple attempts." vsim" 
     (Missing operator before vsim?) 
Not enough arguments for grep at bin/run_regress.pl line 1279, near ""Error: Failure to checkout svverification license feature." vsim" 
syntax error at bin/run_regress.pl line 1279, near ""Error: Failure to checkout svverification license feature." vsim" 
Global symbol "$cur_Test_name" requires explicit package name at bin/run_regress.pl line 1282. 
syntax error at bin/run_regress.pl line 1287, near "}" 

编辑:

,我希望把我的代码是在脚本中的部分地点:

for(my $j=0;$j<$number_of_bfm_based_smoke_100pin_tests;$j++) 
{ 
    chdir("../rtl_mcu_bfm_qfn_100/") or die "Cannot chdir to ../rtl_mcu_bfm_qfn_100"; 
    $curr_test_name = $bfm_based_smoke_100pin_tests[$j] ; 
    process_test_name($curr_test_name); 
    check_status($sim_process_out[1],$bfm_based_smoke_100pin_tests[$j],$seed,"BFM"); 
    $sr_nu++; 
    chdir($start_dir); 
} 

check_status子程序是

sub check_status 
{ 
    my ($pass_fail_string,$cur_test_name,$seed_val,$xdata_mstr) = @_; 
    if ($pass_fail_string =~ /Test FAILED! Test did not end properly/) 
    { 
     # ===== THIS IS WHERE I WANT TO PLACE MY CODE ===== # 
     $incomplete_cnt++ ; 
     printf (STORE_REGRESS_RSLT "|%9d|%78s|%7d|%11s|%12s|\n",$sr_nu,$cur_test_name,$seed_val,"-",$xdata_mstr); 
    } 
    elsif ($pass_fail_string =~ /Test PASSED/) 
    { 
     $pass_cnt++; 
     printf (STORE_REGRESS_RSLT "|%9d|%78s|%7d|%11s|%12s|\n",$sr_nu,$cur_test_name,$seed_val,"PASSED",$xdata_mstr); 
    } 
    elsif ($pass_fail_string =~ /Test FAILED/) 
    { 
     $fail_cnt++; 
     printf (STORE_REGRESS_RSLT "|%9d|%78s|%7d|%11s|%12s|\n",$sr_nu,$cur_test_name,$seed_val,"FAILED",$xdata_mstr); 
    } 
    else 
    { 
     $incomplete_cnt++ ; 
     printf (STORE_REGRESS_RSLT "|%9d|%78s|%7d|%11s|%12s|\n",$sr_nu,$cur_test_name,$seed_val,"-",$xdata_mstr); 
    } 
} 
+3

Perl grep不是系统grep。您必须打开文件并搜索您要查找的行。如果你想使用系统grep,为什么不使用bash? – bytepusher

回答

3

首先,没有理由出去系统为了搜索文件的模式;处理文件。

接下来,如果你这样做system是一个错误的工具。例如,它不会返回命令的STDOUT,而是返回退出状态($?)。在这里你只需要知道是否有出现匹配,而grep出口确实表达了这一点,并被封装到$?的高位中。感谢ysth的评论。

但是,您的代码仍然不会看到错误,因为在if下任何非零返回都为真。您需要分析$?,如果$? >> 8 == 0表示根据grep的手册页有匹配。但是,这种方法的效用仅限于grep。另外,如果设计发生了变化,并且您需要输出(例如,匹配的行),您需要qx(反引号)或其他工具/模块之一。只需用Perl来完成。

这里是沿着你想要

use warnings; 
use strict; 
use feature 'say'; 
use Cwd; 

my @dirs = qw(one two three); # my tests, change to suitable names 
my $logfile = 'log.txt';  
my $incomplete_tests = 'incomplete_tests.log'; 
my $curr_test_name = 'current_test'; 

# regex to search with 
my $err_qr = qr/Error: Failure|Error: Unable|FATAL ERROR:/; #/ 

# Open log file for append 
open my $fh_incomp, '>>', $incomplete_tests 
    or die "Can't open to append $incomplete_tests: $!"; 

my $orig_dir = cwd; 
foreach my $dir (@dirs) 
{ 
    chdir $dir or die "Can't chdir to $dir: $!"; 
    my $updated_name = $curr_test_name . "_$dir"; # update as/if needed 

    open my $fh, '<', $logfile or do { 
     warn "Can't open $logfile: $!"; 
     next; 
    }; 

    while (<$fh>) { 
     say $fh_incomp $updated_name if /$err_qr/; 
    } 

    chdir $orig_dir or die "Can't chdir to $orig_dir: $!"; 
} 
close $fh_incomp; 

什么线工作程序因为我不明白你的问题全是这个基本的,并与一些猜测。它遍历目录列表,检查每个日志文件的名称相同,并且每当一行与预先组成的正则表达式匹配时记录“测试名称”与qr operator

您也可以将其更改为记录错误行(添加打印),或者每个日志文件只记录一次测试名称(匹配后跳至next目录)。

另请注意,chdir没有任何理由,因为您可以轻松使用$dir来形成正确的路径。我使用它来防止您的真实代码执行更多工作,并且实际上可以从$dir中受益。

还有其他方法可以做到这一点,首先在所有目录中搜索日志文件并在每种情况下运行相同的代码。这可以用File::Find::RulePath::Tiny很好地完成。

+0

但grep的状态告诉你它是否匹配 – ysth

+0

啊,完全滑倒了!补充一句,谢谢 – zdim

+0

只要跟进一下,你就有'我的@dirs = qw(一二三); '并且你说要把它改成合适的名字,但在我的情况下,有超过一百(在某些情况下数千)测试名称。在那种情况下我将如何实现它? – Javia1492

相关问题