Nowe posty

xx Dystrybucja pod HP Omen (6)
Wczoraj o 23:30:08
xx [Poradnik] Wyszukiwanie Sterowników (2)
Wczoraj o 21:08:23
lamp Problem z Linux Lite po instalacji (0)
Wczoraj o 19:50:30
xx Ile pingwinów? (1)
Wczoraj o 08:59:24
xx konfiguracja pale moon (0)
2024-03-24, 21:53:42
xx Plasma 6 w Neonie ssie trochę mniej ... (10)
2024-03-23, 02:38:11
xx problem z instalacja sterowników do karty sieciowej (3)
2024-03-18, 18:10:16
xx Plik abc.001 (1)
2024-03-17, 17:48:27
xx Zlecę dopracowanie programu w MatLab (0)
2024-03-13, 15:28:40
xx Linux Mint 21.3 XFCE brak dźwieku po paru minutach (karta muzyczna zintegrowana) (5)
2024-03-12, 23:07:01

Autor Wątek: [Perl] suma liczb (wyciągniętych z pliku)  (Przeczytany 6677 razy)

kapio

  • Gość
[Perl] suma liczb (wyciągniętych z pliku)
« dnia: 2014-04-19, 22:08:33 »
Mam pewien problem i nie mogę sobie z nim poradzić. A dokładnie mam plik, a w nim liczby (kilka kolumn, ale tylko we 2 są liczby) i normalnie wyciąga liczby z kolumny numer 1 i otrzymuje je w takim formacie (print) :
123123129312312312312312312
gdy dam
print $zmienna . "\\n";
otrzymam już normalny wynik
123
123
123
123
321
123
ale gdy chce to dodać to cały czas wypluwa to samo (czyli wynik taki jak wyżej), a ich nie dodaje.
Tak wygląda kod na wyciąganie liczb
#!/usr/bin/env perl
use strict;
use warnings;
open my $file, '<', '/home/info.txt';
while( <$file> ) {
  chomp;
  my @fields = split;
  print $fields[-1] . "\\n";
}
A tutaj kod jak próbowałem to dodać:
#!/usr/bin/env perl
use strict;
use warnings;
use List::Util 'sum';
open my $file, '<', '/home/info.txt';
while( <$file> ) {
  chomp;
  my @fields = split;
  my @acc1 = $fields[-1];
  my $sum;
  map { $sum += $_ } @acc1;
  print $sum . "\\n";
}
wynik
123
123
321
itd.
Drugi kod:
#!/usr/bin/env perl
use strict;
use warnings;
open my $file, '<', '/home/info.txt';
while( <$file> ) {
  chomp;
  my @fields = split;
  my $acc = 0;
  my @acc1 = $fields[-1];
  foreach (@acc1) {
       $acc += $_;
 }
 print $acc . "\\n";
}
wynik taki sam jak wyżej.
Jakaś podpowiedź jak to dodać? W AWK składnia podobna i wszystko ładnie podliczyło, a perl coś nie może tego dodać. Mi się wydaje, że on to widzi jaki jeden ciąg (to co wyrzuca print bez \\n) i dlatego tego nie może dodać. Próbowałem rozbić ciąg tych liczb split, ale tutaj również to samo. Jedyne co uzyskałem to, że liczby były pojedyncze:
1
2
3
4
5
1
2
3

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
[Perl] suma liczb (wyciągniętych z pliku)
« Odpowiedź #1 dnia: 2014-04-20, 10:19:30 »
Zasadniczym mankamentem Twoich skryptów jest ich budowa. Zawartość pętli WHILE wykonuje się raz dla każdej linijki pliku wejściowego. Z tego powodu inicjalizowanie akumulatora w pętli, albo wypisywanie akumulatora w pętli jest bez sensu. Inicjalizować masz przed pętlą, sumować w pętli i wypisać za pętlą.
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

kapio

  • Gość
[Perl] suma liczb (wyciągniętych z pliku)
« Odpowiedź #2 dnia: 2014-04-20, 19:10:06 »
Dzięki Wielkie :) Z 3 razy miałem przygotowanego dużego posta, ale za każdym razem wracałem do kodu, aż się sam z nim uporałem. Miałem błąd z
my $sum = 0;
który siedział w pętli i analogicznie od nowa była przypisywana ta zmienna dlatego potem cały czas otrzymywałem:
a) w pętli wszystkie liczby po kolei
b) poza pętlą ostatnią liczbę.
Tylko jeszcze nie rozumiem do końca:
strict;
przy tej bibliotece musimy deklarować zmienne (tworzymy zmienne lokalne) i ja myślałem, że wtedy nasze zmienne lokalne będą działały przez cały program no i tutaj się myliłem. Ponieważ jak chciałem wydrukować tekst za pętlą to otrzymywałem, że $sum nie istnieje. Poszukałem w google i znalazłem our i na samym początku mam:
our ($sum);
i teraz ładnie skrypt działa, ale dlaczego? Dlaczego zmienna lokalna działa tylko w danym bloku? Czyli w tym przypadku tylko w pętli while? Rozumiem, że to ma nam pomóc, aby nie nakładać na siebie zmiennych (większy program X zmiennych i żeby nie mieć tych samym z innymi wartościami). Ale dlaczego ona zamyka się w danym miejscu? A our informuje, że zmienna X, Y, Z mają działać po całości tak? Cały kod wygląda tak:
#!/usr/bin/env perl
use strict;
use warnings;
open(DATA, "our (@aa, @nums, $sum);
while () {
chomp;
my @aa = split;
my @nums = $aa[-1];
foreach (@nums) {
        $sum += $_;
}
}
print $sum . "\\n";
Jeszcze raz dzięki za pomoc :)