Мої дані виглядають так:
G1 G2 G3 G4
Pf1 NO B1 NO D1
Pf2 NO NO C1 D1
Pf3 A1 B1 NO D1
Pf4 A1 NO C1 D2
Pf5 A3 B2 C2 D3
Pf6 NO B3 NO D3
Моя мета - перевірити в кожному стовпці, чи єелемент (відмінний від випадків "НІ") показується двічі (наприклад, А1 у стовпці 2, наприклад) і лише двічі (якщо він відображається три або більше разів, я не хочу його у висновку) і, якщо так, запишіть відповідні елементи першого стовпця. Отже, бажаний вихід виглядає приблизно так:
Pf3 Pf4 A1
Pf1 Pf3 B1
Pf2 Pf4 C1
Pf5 Pf6 D3
Я намагаюся написати сценарій perl, але мені потрібна допомога, щоб зосередитися на різних кроках. Це те, що я робив до цього часу:
open (HAN, "< $file_in") || die "Impossible open the in_file";
@r = <HAN>;
close (HAN);
for ($i=0; $i<=$#r; $i++){
chomp ($r[$i]);
($Ids, @v) = split (/t/, $r[$i]);
}
}
Але я не можу йти в жодному напрямку! (Мої знання Perl потрібно підштовхнути до вас!)
Гарячі мої точки зору:
як я порівнюю елементи з одного стовпця (або все одно в одному файлі)?
як я можу пов’язати елементи першого стовпця з іншими стовпцями (це можуть бути ключі)?
Будь-яка допомога абсолютно необхідна і ласкаво просимо!
Відповіді:
1 для відповіді № 1use Data::Dumper;
my %hash;
while (<DATA>) {
next if $.==1;
chomp;
my ($first,@others) = (split /s+/);
for (@others){
$hash{$_}.=" ".$first;
}
}
print Dumper %hash;
__DATA__
G1 G2 G3 G4
Pf1 NO B1 NO D1
Pf2 NO NO C1 D1
Pf3 A1 B1 NO D1
Pf4 A1 NO C1 D2
Pf5 A3 B2 C2 D3
Pf6 NO B3 NO D3
Що я тут використовую? (хитрощі)
while (<DATA>){BLOCK}
- читати дані з конкретного розділу DATA у файлі сценарію Perl. (так, ви можете помістити сюди дані тесту, якщо хочете. Але не зберігайте все! Це не смітник!)
next if $.==1
- $.
- спеціальна змінна, що зберігає номер рядка вхідних даних. як "індекс".
chomp;
- повертатися до while(<DATA>)
. Деякі змінні в Perl приховано. У функціях - @_
масив вхідних параметрів. І завжди програмістами Perl подобається користуватися $_
- You
змінна
І це while(<DATA>)
дійсно прихований while(defined($_ = <DATA>))
.
Функція chomp
використовувати hidden-You
змінну і спробуйте порубати n символ в кінці.
Функція split /REGEX/
також приймати змінну за замовчуванням hidden-You
змінна ($_
)
1 для відповіді № 2
Perl multi liner :),
perl -anE "
/^S/ or next;
$k = shift @F;
push @{$t{$_}}, $k for@F;
}{
@$_-1==2 and say join" ",@$_ for map [@{$t{$_}},$_], sort keys%t;
" file