我修改一个现有的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);
}
答案 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::Rule或Path::Tiny很好地完成。