Почему скрипт Perl запрашивает «глобальное объявление», когда я объявляю что-то в цикле for? - PullRequest
0 голосов
/ 05 августа 2009

Я читаю $digit из infile и хочу напечатать его до outfile . Но скрипт Perl выдает ошибку, в которой говорится, что «глобальному символу« $ digit »требуется явное имя пакета». Но если я объявлю это глобально, $digit='', тогда это значение будет напечатано в outfile вместо значения, извлеченного / прочитанного из infile . Любые предложения относительно того, что должно быть сделано?

Вот как я это делаю:

    my $digit=''; 
    open (DATA, "</usr/infile") || die "cant open infile\n"; #file from digit has to read

    while (<DATA>){
        ($digit)= $_=~ /\s9\s(\d+)/; #regex to capture digit '234' from ' 9 234'
        if ($digit ne ""){
        print "digit is $digit\n"; # this prints fine
        }
    }

    open (FILE, ">/usr/outfile") || die "cant open outfile\n"; #file to which digit has to be finally written
    print FILE "9   $digit"; #$digit takes in the value declared globally i.e. ''

    close(DATA);
    close (FILE);

Ответы [ 4 ]

2 голосов
/ 05 августа 2009
while (<DATA>){
    my ($digit)= $_=~ /\s9\s(\d+)/; #regex to capture digit '234' from ' 9 234'
    if ($digit ne ""){
    print "digit is $digit\n"; # this prints fine
    }
}

Лексические переменные (созданные с помощью my) существуют в пределах области, в которой они объявлены, поэтому $ digit создается и уничтожается каждый раз в цикле.

2 голосов
/ 05 августа 2009

Ваш $digit находится в цикле while, а затем вы пытаетесь получить к нему доступ с помощью строки:

print FILE "9   $digit";

Вы должны объявить его вне цикла while, чтобы это было видно в этой строке.

Или, что еще лучше, просто откройте свой выходной файл перед циклом и запишите цифру в выходной файл в цикле и сохраняйте переменную $digit в пределах цикла.

Если вам нужен только последний экземпляр, соответствующий вашему регулярному выражению, тогда:

#!/usr/bin/perl
use strict;

open (DATA, "infile.txt")  || die("cant open infile\n");   

my $digit = "";
while (<DATA>) {
    chomp;
    if (/\s9\s(\d+)/) #regex to capture digit '234' from ' 9 234' 
    {
       print "Found digit is $1\n"; # 
       $digit = $1;
    }
}
close(DATA);

if ($digit ne "") {
open (FILE, ">outfile.txt") || die("cant open outfile\n"); 
print FILE "9   $digit\n";
close(FILE);
}
else
{
    print "No digit found!\n";
}
exit;

Если вы хотите получить все экземпляры в infile, где совпадает ваше регулярное выражение, то вам нужно выполнить следующее.

#!/usr/bin/perl
use strict;

open (DATA, "</usr/infile")  || die("cant open infile\n");   
open (FILE, ">/usr/outfile") || die("cant open outfile\n"); 

while (<DATA>) {
    chomp;
    if (/\s9\s(\d+)/) #regex to capture digit '234' from ' 9 234' 
    {
       print "Found digit is $1\n"; # 
       print FILE "9   $1\n";
    }
}


close(DATA);
close (FILE);
exit;
1 голос
/ 05 августа 2009

Не объявляйте $digit с my внутри цикла while(); объявите это только снаружи:

my $digit;
while( <DATA> ) {
    # stuff that sets $digit... 
}

open( FILE , '>out' );
print FILE $digit;
0 голосов
/ 05 августа 2009

Вы объявили $digits локальным для области действия цикла while, используя my. $digit в операторе print находится вне области видимости, и именно это вызывает сообщение.

Чтобы исправить это, объявите my $digit до цикла while или объявите его с our вместо my, чтобы сделать его глобальным.

Я бы сделал следующее:

use strict;
use warnings;

my $digit = "None";  # None if there are no digits found

open (DATA, "</usr/infile") || die "cant open infile\n"; #file from digit has to read
while (<DATA>){    
    ($digit) = $_=~ /\s9\s(\d+)/; #regex to capture digit " 9 234"    
    if ($digit ne ""){    
        print "digit is $digit\n"; # this prints fine    
    }
}
open (FILE, ">/usr/outfile") || die "cant open outfile\n"; #file to which digit has to be finally written
print FILE "9   $digit";
close(DATA);
close(FILE);

Если вы не получили цифру, вы получите None для $digit.

Надеюсь, это поможет.

...