Как увеличить (изменить) строку для каждого прохода в цикле

ЦЕЛЬ:

Файл, разделенный табуляцией, содержит разные строки. Некоторые элементы идентичны, некоторые нет. Я хотел бы «объединить» определенные элементы в одной строке. Однако в этой операции мне нужно внести изменения в конкретный элемент, чтобы отделить их друг от друга, например. добавление числа в конец.

ВВОД (в @input):

File1 2 range-2 operation execute:error 12345444,294837,298774
File2 3 range-1 default range:error 349928,37224
...

Я хотел бы объединить «поле» execute:error с 12345444,294837,298774 и range:error с 349928,37224, чтобы получить это:

ВЫХОД:

execute:error-1
12345444
execute:error-2
294837
execute:error-3
298774
range:error-1
349928
range:error-2
37224

PERL CODE: я думал о выполнении цикла foreach для элементов в @input, используя, например, хэши для подсчета количества «строк» ​​в последнем «столбце», разделенных запятыми, и каким-то образом добавить число (например, равное общему хешу -1, создавая счетчик?). Но, это немного над моей головой. Как, я могу это сделать? Я попробовал немного ниже, но остановился примерно через два часа попыток, чтения и поиска похожих вопросов. Может быть, я не должен использовать хэш?

my @output = ();
foreach (@input) {
    our(@F) = split('\t', $_, 0);
    my @end_numbers = split(',', $F[5], 0);
    %count;
    foreach (@end_numbers) {
        ++$count{$_};
        my $counts = keys %count;
        my $output = $F[4] . (adding a value here, e.g. $counts -1 for each loop itteration ) "\n" . $_;
        push (@output, $output);
}
}

РЕШЕНИЕ: По предложению @ikegami.

my @output = ();
my %counts = ();
foreach (@input) {
    chomp $_;
    my @fields = split(/\t/, $_, 0);
    for my $num (split /,/, $fields[5]) {
    ++$counts{$fields[4]};
    my $output = $fields[4] . "_" . $counts{$fields[4]} . "\n" . $num . "\n";
    push (@output, $output);
    }
}

person JamesT    schedule 31.07.2013    source источник
comment
Вы никогда не должны использовать our сохранение при принудительном выполнении (например, @ISA, @EXPORT и @EXPORT_OK)   -  person ikegami    schedule 31.07.2013
comment
Я внес некоторые изменения в часть, благодаря вашему вкладу @ikegami, и теперь она работает нормально. Спасибо также за то, что указали мне на неправильное использование слова «наш» в моей программе.   -  person JamesT    schedule 31.07.2013


Ответы (2)


Значение, которое вы пытаетесь объединить, равно $count{$_}.

my %counts;
while (<>) {
    chomp;
    my ($class, $nums) = ( split /\t/ )[4,5];

    for my $num (split /,/, $nums) {
       ++$counts{$class};
       print "$class-$counts{$class}\n";
       print "$num\n";
    }
}

Или сохранить строку:

       printf "%s-%s\n", $class, ++$counts{$class};
       printf "%s\n", $num;

Если вы хотите, чтобы счетчик сбрасывался для каждой строки ввода, используйте my $count; внутри внешнего цикла вместо my %counts; и используйте $count вместо $counts{$class}.

person ikegami    schedule 31.07.2013

Просто используйте функцию карты, чтобы добавить строку $F[4].--$count."\n$_\n" к каждому числу в списке $F[5].

foreach (@input) {
    my @F = split(/\t/, $_, 0);
    my $count = 0;
    my @end_numbers = map { $F[4]. --$count .qq|\n$_\n| } split(/,/, $F[5], 0);
    print @end_numbers;
}
person jvverde    schedule 31.07.2013
comment
Обратите внимание, что это отличается по поведению от кода OP. (Попробуйте добавить третью строку ввода: ... execute:error 1234567890) - person ikegami; 31.07.2013
comment
@ikegami Я не понимаю твоей точки зрения. Вы меняете имя переменной с $c на $count, что нормально, но почему вы меняете его на увеличение, а не на уменьшение? И не вижу никаких проблем с любым количеством строк, если только вы не говорите о... буквальном толковании. - person jvverde; 31.07.2013
comment
Извините, я упустил хитрость вашего кода (выполнение арифметических операций над чем-то, что не является числом). Так что $count тоже не очень хорошее имя. Действительно запутанный подход. - person ikegami; 31.07.2013
comment
@ikegami, но $count - это число, я просто использую его как операнд в операции конкатенации строк. Мне жаль, что вам это не нравится, но это работает, и в этом нет ничего плохого. - person jvverde; 01.08.2013