使用grep通过perl在不同目录中的文件中查找匹配模式

时间:2017-08-15 21:21:40

标签: perl grep

我修改一个现有的perl脚本,它通过转到他们的目录并解析pass,fail或incomplete来检查运行的某些测试的状态。我想扩展此脚本以生成包含基于3个字符串的未完成测试的子列表:

mix.exs

每个测试名称都有自己的目录,目录中有一个名为defp deps的日志文件。我可以使用"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

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

但这不能编译,我是perl的新手,所以我很难弄清楚如何正确使用$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 ../../"; 而没有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);
}

1 个答案:

答案 0 :(得分:3)

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

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

但是,您的代码仍然不会看到错误,因为if下的任何非零返回都为真。根据{{​​1}}的手册页,您需要分析$?,以及$? >> 8 == 0是否意味着匹配。但是,这种方法的效用仅限于grep

此外,如果设计发生变化并且您需要输出(例如匹配的行),则需要grep(反引号)或其他一些工具/模块。只需在Perl中完成所有操作。

这是一个符合你想要的工作计划

qx

由于我不了解你的完整问题,这是基本的,并且有一些猜测。它遍历一个目录列表,检查每个目录中的相同名称的日志文件,并在每次一行与qr operator提前组成的正则表达式匹配时记录“测试名称”。

您可以将其更改为记录错误行(添加打印),或者每个日志文件仅记录一次测试名称(一旦匹配,请跳至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; 目录)。

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

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