下面是处理
new.txt
文件中写入的行的代码。
my $bankNameTest;
my $bankName;
my @lines;
my $document = do {
local $/ = undef;
open my $fh, "<", "new.txt"
or die "could not open $file: $!";
<$fh>;
};
chomp ($document);
print "$document is doc\n";
@lines = split (/\n/,$document);
foreach my $test (@lines) {
$bankNameTest=glob ("${test}/wint_nightly_nfarm_*.main.20241216.4262507") ;
chomp ($bankNameTest);
print "$bankNameTest is testbankname\n";
$bankName=`ls -d $bankNameTest | sed -r "s?${var}/??g" | sed -r "s/wint_nightly_nfarm_//g" | sed -r "s/.main.20241216.4262507//g"`;
chomp ($bankName);
print "$bankName is the bankName\n";
}
new.txt
的内容是:
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/2487964_brd_launch/cap_allegro_view
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/FIND/enh_find/DRC_MARKERS/hierdsn_incomp_entry
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/crossprobe/03_between_cap_allegroviewer/dsn_schm_page
输出是:
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/2487964_brd_launch/cap_allegro_view/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname
capture_viewer is the bankName
is testbankname
is the bankName
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/crossprobe/03_between_cap_allegroviewer/dsn_schm_page_and_part_name_with_special_chars/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname
capture_viewer is the bankName
此处,new.txt 的第二行未得到正确处理。
预期输出:
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/2487964_brd_launch/cap_allegro_view/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname
capture_viewer is the bankName
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/FIND/enh_find/DRC_MARKERS/hierdsn_incomp_entry/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname
capture_viewer is the bankName
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/crossprobe/03_between_cap_allegroviewer/dsn_schm_page_and_part_name_with_special_chars/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname
capture_viewer is the bankName
不确定问题出在哪里? new.txt 中似乎存在一些与字符相关的问题。需要有“预期输出”中提到的输出。
首先,让我们简化一些程序结构(正如 @ikegami 在他的评论中简要指出的那样)。
您想要处理文件的行,但您做了很多工作才能将所有内容合并为单个值,然后再次将其拆分。所有代码就是这个
while
循环:
open my $fh, '<', 'new.txt' or die "could not open $file: $!";
while( <$fh> ) {
chomp;
...
}
现在,循环内的内容有点棘手,因为我认为你可能会以困难的方式做所有事情。
您似乎想找到一个您可能不知道名称中间是什么的文件。你有这个全局模式:
${test}/wint_nightly_nfarm_*.main.20241216.4262507
当您在输出中看到两行没有任何文件名时,我的第一个想法是该模式与其中一个目录中的文件不匹配。您查看该目录并看到您想要的文件了吗?
由于全局没有匹配,
$bankNameTest
是空的,这几乎破坏了循环的其余部分。
每当您与程序之外的某些内容交互时,请在使用结果之前检查它是否有效:
my $file = glob(...);
unless( defined $file ) { ... }
如果没有文件名,则无法继续迭代。您可能想输出警告然后跳过其他所有内容:
my $file = glob(...);
unless( defined $file ) {
warn "Did not find file";
next;
}
而且,这不仅仅是关于调用
glob
的上下文。如果你在列表上下文中没有找到该文件,你仍然会遇到这个问题:
my( $file ) = glob(...); # file not there
之后,在 glob 确实起作用的情况下,你还有更多的技巧。
$bankName=`ls -d $bankNameTest | sed -r "s?${var}/??g" | sed -r "s/wint_nightly_nfarm_//g" | sed -r "s/.main.20241216.4262507//g"`;
我不确定你想要这个做什么。
ls -d ...
只是输出目录名称,我猜这是启动管道输入的另一种方式。之后就是一堆 sed。但是,Perl 可以完成 sed 所做的一切:
$bankName = $bankNameTest;
$bankname =~ s/...//; # trying to get rid of the directory?
$bankname =~ s/wint_nightly_nfarm_//;
$bankname =~ s/.main.20241216.4262507//;
这里不需要
/g
,因为我认为您希望其中任何一个在多个地方匹配。
我认为您正在尝试从全局模式的通配符部分获取这一点。但你不需要破坏性地削掉一根绳子:
my $bankname;
if( $bankNameTest =~ m/wint_nightly_nfarm_(.*)\.main\.20241216\.4262507/ ) {
$bankname = $1
}
要认识到,任何时候您想要进行某种文本操作,Perl 都可以在 Perl 内部完成,而且可能比其他任何操作都更好、更简单。
但是,将这两件事放在一起,我可能倾向于使用
readdir
,它不包含目录名,并直接匹配文件名来捕获有趣的部分。一旦找到该文件,我就不再寻找:
open my $fh, '<', $file or die "could not open $file: $!";
while( <$fh> ) {
chomp;
print "$_ is testbankname\n";
opendir my $dh, $_ or do {
warn "Could not open dir <$_>: $!";
next;
}
my $bankName;
while( my $f = readdir($dh) ) {
next unless $f =~ /wint_nightly_nfarm_(.*)\.main\.20241216\.4262507/;
$bankName = $1;
last;
}
print "$bankName is the bankName\n";
}