[+] Pobieranie losowej linii z pliku

Potrzebujesz pomocy z C, C++, perl, python, itp.
Akkon
Junior Member
Posty: 833
Rejestracja: 09 listopada 2007, 14:06

[+] Pobieranie losowej linii z pliku

Post autor: Akkon »

Mam plik tekstowy a w nim kilkaset linijek. Poszukuję jakiegoś mechanizmu, który z tego pliku pobierałby losowo np. jedną linijkę. Na razie znalazłem coś pośredniego

Kod: Zaznacz cały

sed -n xp plik
dzięki temu sed wyświetla x linię pliku, ale brak tu elementu losowości, na którym mi zależy.

Z góry dziękuję za pomoc
ponton
Beginner
Posty: 406
Rejestracja: 24 stycznia 2007, 01:40
Lokalizacja: Kalisz/Wroc³aw

Post autor: ponton »

Na szybko w Perlu: wczytuje plik (podany jako pierwszy argument) do pamięci, a potem losuje wiersz i go wypisuje:

Kod: Zaznacz cały

#!/usr/bin/perl

if ($#ARGV > 0)
{
        open(FILE, $ARGV[1]);
        @file = <FILE>;
        my $index = rand @file;
        my $line = @file[$index];
        print $line;
        close FILE;
}
else
{
        print "Missing argument!\n"
}
Akkon
Junior Member
Posty: 833
Rejestracja: 09 listopada 2007, 14:06

Post autor: Akkon »

ponton pisze:Na szybko w Perlu
Dzięki. Gdybyś był jeszcze tak miły i napisał, takiej całkowitej lamie z programowania jak ja :mrgreen: , w którym dokładnie miejscu mam podać lokalizację do mojego pliku?
beel
Beginner
Posty: 340
Rejestracja: 28 marca 2007, 07:06

Post autor: beel »

Albo z Pythonem, na jeszcze szybciej:

Kod: Zaznacz cały

import linecache
import random

filePath = "/home/beel/zadanie/przypadkowy"

liczba_linii = len(open(filePath, 'rU').readlines())
print linecache.getline(filePath, random.randint(0,liczba_linii))
linecache.clearcache()
¦cieżkę widać gdzie podać. Linie losuje na całej zawartości pliku.
Akkon
Junior Member
Posty: 833
Rejestracja: 09 listopada 2007, 14:06

Post autor: Akkon »

beel, Twój skrypcik pięknie działa - dzięki. Mam tylko jedno pytanie. Edytowałeś swojego posta może, bo wcześniej było tak:

Kod: Zaznacz cały

print linecache.getline(filePath, random.randint(1,100))
linecache.clearcache()
a jest tak:

Kod: Zaznacz cały

liczba_linii = len(open(filePath, 'rU').readlines())
print linecache.getline(filePath, random.randint(0,liczba_linii))
linecache.clearcache()
Rozumiem, że wcześniej było tak, że wybierał linie z przedziału od 1 do 100?

Kod: Zaznacz cały

random.randint(1,100)
?
beel
Beginner
Posty: 340
Rejestracja: 28 marca 2007, 07:06

Post autor: beel »

Tak, zgadza się, edytowałem aby .. wyliczał linie i z całego zbioru losował. Wcześniej trzeba było ustawiać na sztywno..
ponton
Beginner
Posty: 406
Rejestracja: 24 stycznia 2007, 01:40
Lokalizacja: Kalisz/Wroc³aw

Post autor: ponton »

Akkon pisze:
ponton pisze:Na szybko w Perlu
Dzięki. Gdybyś był jeszcze tak miły i napisał, takiej całkowitej lamie z programowania jak ja :mrgreen: , w którym dokładnie miejscu mam podać lokalizację do mojego pliku?
W żadnym, zapisujesz to do pliku np. randomline.pl, nadajesz mu prawa do uruchomienia (chmod +x randomline.pl) i wywołujesz:

Kod: Zaznacz cały

./randomline.pl plik.txt
beel pisze:Albo z Pythonem, na jeszcze szybciej:

Kod: Zaznacz cały

import linecache
import random

filePath = "/home/beel/zadanie/przypadkowy"

liczba_linii = len(open(filePath, 'rU').readlines())
print linecache.getline(filePath, random.randint(0,liczba_linii))
linecache.clearcache()
¦cieżkę widać gdzie podać. Linie losuje na całej zawartości pliku.
To jest trochę nieoptymalne najpierw wczytać plik, żeby policzyć liczbę wierszy, a potem znowu wczytać plik, żeby wyświetlić wylosowany wiersz. ]import random

filePath = "/home/beel/zadanie/przypadkowy"

zawartosc = open(filePath, 'rU').readlines()
wiersz = random.randint(0, len(zawartosc))
print zawartosc[wiersz][/code]

Do kompletu jeszcze wersja w AWK-u. Przetestuj i wybierz najszybszą. :P

Kod: Zaznacz cały

#!/usr/bin/awk -f

BEGIN {
	srand()
	i = 0
}

{
	lines[i] = $0
	++i
}

END {
	print lines[int(rand()*i)]
}

Kod: Zaznacz cały

./randomline.awk < plik.txt
beel
Beginner
Posty: 340
Rejestracja: 28 marca 2007, 07:06

Post autor: beel »

[quote="ponton"]To jest trochę nieoptymalne najpierw wczytać plik, żeby policzyć liczbę wierszy, a potem znowu wczytać plik, żeby wyświetlić wylosowany wiersz. ]
Zastrzegałem, że na szybko i uwagi na to nie zwracałem..

Dałbym:

Kod: Zaznacz cały

wiersz = random.randint(0, len(zawartosc)-1)
Akkon
Junior Member
Posty: 833
Rejestracja: 09 listopada 2007, 14:06

Post autor: Akkon »

Jeszcze raz Wam dziękuję za pomoc. Do meritum:
ponton pisze:zapisujesz to do pliku np. randomline.pl, nadajesz mu prawa do uruchomienia (chmod +x randomline.pl) i wywołujesz
Niestety nie działa cały czas otrzymuję komunikat

Kod: Zaznacz cały

Missing argument!
ponton pisze:Do kompletu jeszcze wersja w AWK-u. Przetestuj i wybierz najszybszą. :P
Tu jest ok.
beel pisze:Dałbym:
Kod:
wiersz = random.randint(0, len(zawartosc)-1)
Skrypt po modyfikacjach działa. Rożnicy w szybkości nie zauważyłem :-D

Po wstępnych testach sądzę, że AWK będzie najwygodniejszy, gdyż plik z danymi nie musi być określony "na sztywno" w skrypcie tak jak jest w propozycji beela, choć z punktu widzenia moich potrzeb to jest w zasadzie marginalna niedogodność.
ponton
Beginner
Posty: 406
Rejestracja: 24 stycznia 2007, 01:40
Lokalizacja: Kalisz/Wroc³aw

Post autor: ponton »

Akkon pisze:Niestety nie działa cały czas otrzymuję komunikat

Kod: Zaznacz cały

Missing argument!
Nie piszę w Perlu i jakiś problem miałem z liczbą argumentów... Możesz wykasować tego if-a i else-a i zostawić tylko to, co jest w pierwszej klamrze.
ODPOWIEDZ