Nowe posty

xx Odpowiednie wykorzystanie rdzeni P i E procesora (1)
Dzisiaj o 06:44:59
xx Samba DC/AD problem z DNS (0)
2024-07-25, 12:42:23
xx DNS i WWW na virtualbox (4)
2024-07-24, 10:30:38
xx Instalacja Manjaro Linux (11)
2024-07-13, 22:57:31
xx Linux Lite 6.6. Po uruchomieniu z DVD przeglądarka Chrome jest nieaktywna (12)
2024-07-10, 22:33:30
xx Laptop MSI CR500 - nie akceptuje linuksa (6)
2024-07-03, 05:30:18
xx Co to jest ? (3)
2024-07-02, 13:36:58
xx Nowa wersja libreoffice (1)
2024-06-30, 18:22:49
xx Dystrybucja - środowisko graficzna dla amigowca (MUI) (4)
2024-06-30, 12:14:25
xx Jaki kod błędu zwracać z kernela? (3)
2024-06-09, 12:29:22

Autor Wątek: [Perl] suma liczb (wyciągniętych z pliku)  (Przeczytany 6844 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: 3077
  • 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 :)