Невозможно правильно проанализировать файл;Глоб не работает - PullRequest
2 голосов
/ 06 ноября 2019

Я пытаюсь написать сценарий Perl, который в основном проверяет, существует ли конкретный файл, соответствующий регулярному выражению, в определенном каталоге. Вот мой код:

use strict;
use warnings;

system ("grep PATH $ENV{MODEL_ROOT}/<....>/paths.tcl > \$MODEL_ROOT/hip_paths.csv");
system("sed -i 's/) /,/g' \$MODEL_ROOT/paths.csv");
system("sed -i 's/set G_L.*,//g' \$MODEL_ROOT/paths.csv");

my @glob;

my $file = "$ENV{MODEL_ROOT}/paths.csv" or die "CSV File is not present\n";
open(my $file_data, '<', $file) or die "Could not open '$file' $!\n";

while (my @line = <$file_data>) {
  system ("printf \"@line\" >> fields"); #For debug
  foreach my $path (@line)
 {   
     $path =~ m/^.*proj\/(.*)\/<blah>/; #To find 'name'
     if (glob ("$path/*0p765v_125c*.ldb")) #Check if file exists in $path with said pattern
     {   
            @glob = glob ("$path/*0p765v_125c*.ldb");
            print "File exists for $1 in path $path: @glob\n"
     } 
     else 
     {
        print "Does not exist for $1 in path $path\n";
     } 
  }
}
close $file_data

paths.csv выглядит следующим образом: (Не удается опубликовать фактический путь из-за проблем с TM и C)

/(path-to-proj)/proj/name1/version1/abc  
/(path-to-proj)/proj/name2/version2/abc  
/(path-to-proj)/proj/name3/version3/abc  
/(path-to-proj)/proj/name4/version4/abc  
/(path-to-proj)/proj/name5/version5/abc   

(путьto proj) буквенно-цифровой,
proj только алфавитный,
name <> буквенно-цифровой и может содержать подчеркивание,
version <> буквенно-цифровой

Я знаю, что всеэти пути имеют файл, который соответствует указанному шаблону. Тем не менее, результат моего кода выглядит примерно так:

File exists for name1 in path /(path-to-proj)/proj/name1/version1/abc
: /(path-to-proj)/proj/name1/version1/abc
Does not exist for name2 in path /(path-to-proj)/proj/name2/version2/abc

File exists for name3 in path /(path-to-proj)/proj/name3/version3/abc
: /(path-to-proj)/proj/name3/version3/abc
Does not exist for name4 in path /(path-to-proj)/proj/name4/version4/abc

Результаты чередуются между «Существует» и «Не существует». Что я делаю не так?

1 Ответ

4 голосов
/ 06 ноября 2019

Операторы (например, glob) функционируют по-разному в зависимости от того, оцениваются ли они в скалярном контексте или контексте списка.

glob в скалярном контексте действует как итератор. Он возвращает следующее совпадение, пока не вернет undef, чтобы указать, что больше нечего возвращать. Неважно, изменится ли аргумент.

$ perl -e'for (1..7) { my $glob = glob("*"); CORE::say "$_ $glob"; }'
1 a.xml
2 b.xml
3 
4 a.xml
5 b.xml
6 
7 a.xml

Вы не хотите этого. Вы хотите назвать это в контексте списка. Поэтому замените

if (glob ("$path/*0p765v_125c*.ldb")) {
        @glob = glob ("$path/*0p765v_125c*.ldb");

на

if ( my @ldb_paths = glob("$path/*0p765v_125c*.ldb") ) {

или

if ( my ($ldb_path) = glob("$path/*0p765v_125c*.ldb") ) {

Второй вариант получает только первое совпадение, игнорируя остальные. Парены в левой части назначения имеют решающее значение для создания необходимого контекста списка для правой части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...