2012-03-21 2 views
-1

У меня есть текстовый файл со следующим содержимым:Perl вложенных циклов

NW1 SN1 DEV1 
NW2 SN1 DEV2 

Я написал скрипт на Perl, чтобы перебрать файл, но он работает только один раз. Код:

open(INPUT1,"input.txt"); 
@input_array = <INPUT1>; 

for($i=0;$i<@input_array;$i++) 
{ 
    my ($ser,$node,@dev)=split(/ +/,$input_array[$i]); 

    for($x=0;$x<@dev;$x++) 
    { 
     print("Hi"); 
    } 
} 

Сценарий выполняет итерацию для первой строки, но не выполняет итерацию второй строки.

+0

файл похож на первую строку NW1 SN1 DEV1 вторая строка NW1 SN1 DEV2 –

+7

Ну, ваша программа печатает 'HiHi' (два раза« Привет »), которая выглядит хорошо для меня. Код печатает «Привет» для каждого «DEV» на каждой строке, и в каждой строке есть две строки с одним «DEV». Если вы хотите напечатать каждый «Привет» в своей собственной строке, вам нужно добавить новую строку ('\ n'), например' print 'Hi \ n ";' - в противном случае вы могли бы рассказать нам, какой результат вы ожидаете? – vstm

+0

эй спасибо, что он работает отлично сейчас ..mistake с тем, как я беру в массиве ввода ... я использую пока ... –

ответ

0

код вы вывесили может быть улучшена, и воспитывался к более современным стандартам.

  • Используется ручка десктопа file INPUT1.
  • Он не использует 3-arg open.
  • Не используется strict или warnings (see this question).
  • Он не проверяет возвращаемое значение open или close. (Вот что делает линия autodie в следующем коде)
  • Он использует C-style for loops, когда это не нужно.
  • Он загружает весь файл в память, хотя он имеет дело только с файлом по одной строке за раз.
use strict; 
use warnings; 
use autodie; # checks return value of open and close for us 

# 3 arg open 
open(my $in_fh, '<', 'input.txt'); 

# don't read the file into memory until needed 
while(<$in_fh>){ 
    # using $_ simplified this line 
    my ($ser,$node,@dev) = split; 

    # no need to track the indices just loop over the array 
    for my $dev (@dev){ 
     print "Hi\n"; 
    } 
} 

close $in_fh; 

Если по какой-то причине вам действительно нужны показатели в @dev массиве было бы лучше, чтобы написать это:

for my $x (0..$#dev){ 
    ... 
} 

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

while(my $line = <$in_fh>){ 
    my ($ser,$node,@dev) = split/+/ $line; 
    ... 
} 
-3

Вы забыли войти в режим slurp оператора '<>'. Для того, чтобы сосать в полный файл, вы должны сделать это:

open(INPUT1,"input.txt"); 
undef $/; 
@input_array = split(/\r?\n/, <INPUT1>); 
close INPUT1; 

или еще лучше так:

open(INPUT1,"input.txt"); 
while(<INPUT1>) { 
    chomp; 
    my ($ser,$node,@dev)=split(/ +/,$_); 

    for($x=0;$x<@dev;$x++) 
    { 
    print("Hi"); 
    } 
} 
close INPUT1; 
+2

Присвоение '<>' списку будет читать весь файл, как массив строк , Конечно, код с 'while' определенно более масштабируемый и идиоматический для этого сценария. – tripleee

Смежные вопросы