Итак, у меня есть некоторые данные в форме с разделителями табуляции:
Windows Department1 Enterprise
Windows Department1 Home
Linux Department2 Santiago
Windows Department1 Professional
Windows Department1 Enterprise
Windows Department2 Enterprise
В этом случае мне нужно сначала сопоставить первый столбец и получить количество каждого значения во 2-м и 3-м столбцах. Типа, чтобы соответствовать количеству точных совпадений. Итак, чтобы получить что-то вроде:
Windows Department1 Enterprise = 2
Windows Department2 Professional = 1
Linux Department2 Santiago = 1
Windows Department3 Home = 1
Windows Department2 Enterprise = 1
Итак, я перепробовал множество вещей, причем это была последняя попытка, и я получил много разных нежелательных результатов:
use strict;
use warnings;
my %seen;
my $count = 0;
while (<INPUTFILE>) {
my ($app,$dep,$name) = split(/\t/,$_);
if ($app.$dep.$name eq 'Windows.Department1.Professional') {
unless ($seen{$app.$dep.name}++) {
$count++;
}
}
}
print $app . " " . $dep . " " . $name . " " . $count++
Но это не делает удаленно то, что я хочу. и просто печатает последние значения со счетом. Я хочу установить уникальность $app
один раз, а затем сопоставить второе и третье значения, чтобы получить счет. Помимо этого, мне нужно вручную сопоставить каждый элемент с eq
, а в приведенном выше примере удаленно не показано количество данных в файле, так что это станет проблемой. Буду очень признателен за любую помощь.
Сначала создайте хеш-ключ с тем, что вы хотите считать уникальным: комбинация $app, $dep и $name. Вы можете использовать для этого комбинированный ключ, но давайте воспользуемся многомерным хэшем, чтобы сохранить ключи отдельно на будущее. Каждый промежуточный уровень автоматически будет самооживленный, когда мы увеличим счетчик.
use strict;
use warnings;
open my $input, '<', $filename or die "open $filename failed: $!";
my %counts;
while (my $line = <$input>) {
chomp $line; # otherwise trailing field will contain a newline
my ($app, $dep, $name) = split /\t/, $line;
$counts{$app}{$dep}{$name}++;
}
Затем выполните итерацию по хэшу, чтобы распечатать каждый счет.
foreach my $app (sort keys %counts) {
my $app_counts = $counts{$app};
foreach my $dep (sort keys %$app_counts) {
my $dep_counts = $app_counts->{$dep};
foreach my $name (sort keys %$dep_counts) {
my $count = $dep_counts->{$name};
print "$app $dep $name $count\n";
}
}
}
Вы уверены, что ваш ввод разделен табуляцией? Содержит ли он строки, в которых нет данных? Попробуйте split ' ', $line
разделить на любые пробелы.
Моя вина. Я все еще разделяла $_
и не заметила, как ты определил $line
Спасибо!
Если вы знаете, что ваши поля не содержат пробелов, используйте \s+
, который будет работать для любой комбинации табуляции и пробелов в качестве разделителей.
Особый случай ' '
для расколоть похож на /\s+/
.
@JoeMcMahon, спасибо. Мои поля содержат пробелы, поэтому я должен разделить /\t/
Привет спасибо. Я просто получаю целую кучу
Use of uninitialized value $dep in hash element at count_matches.pl line 11, <$input> line 1
в качестве вывода.