代码未正确处理文本文件的几行

问题描述 投票:0回答:1

下面是处理

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 中似乎存在一些与字符相关的问题。需要有“预期输出”中提到的输出。

perl
1个回答
0
投票

首先,让我们简化一些程序结构(正如 @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, '<', 'new.txt' or die "could not open $file: $!";
while( <$fh> ) {
    chomp;
    print "$_ is testbankname\n";
    
    opendir $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";
    }   
© www.soinside.com 2019 - 2024. All rights reserved.