Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    [C/C++/BASH/PERL] Estrarre casualmente x righe da file

    Salve a tutti, come al solito ho una domanda da porre alla vostra attenzione:
    dato un file1 di n righe (con n abbastanza grande, circa 2000), come posso estrarre x righe randomicamente (con x abbastanza piccolo, circa 200), per creare quindi un secondo file2?
    Mi sembrava ridicolo scrivere un programma in c/c++ che estragga randomicamente x numeri tra 1 e 2000 e poi scrivere uno script in bash che stampa quelle x righe...
    Qualcuno ha un metodo più elegante da proporre?

    Forse posso utilizzare sed o awk in connessione con $RANDOM?
    O magari esiste già qualche script in perl?

    Grazie per le risposte.

  2. #2
    quindi in che linguaggio intendi farlo, partendo dal presupposto che ti daremo una mano ?
    Experience is what you get when you don’t get what you want

  3. #3
    Ho proposto vari linguaggi, dato che non ho una preferenza...
    Pensavo che in bash o in perl si possano manipolare meglio i file...
    Ma l' importante è il risultato e non il mezzo col quale lo ottengo.

    Comunque in bash l' idea è quella di generare un numero casuale con $RANDOM e poi magari numerare le righe del file da cui estrarre le righe e prendere solo la riga numero $RANDOM...
    In più dovrei controllare che la riga estratta non sia già stata estratta in precedenza...
    Qualche aiuto?

  4. #4
    Premetto che quello che hai pensato di fare in bash si può fare (e lo devi fare cmq per risolvere il problema) con gli altri linguaggi (credo che il modo più semplice e anche "portabile" sia quello di usare c++ e perl, inoltre un compilato è più veloce)...
    Cmq puoi prima calcolarti i valori random e metterli in un vettore e poi leggere le righe (in questo modo potrai controllare i valori precedentemente inseriti)...
    Experience is what you get when you don’t get what you want

  5. #5
    ti o fatto un abozzo in cpp:
    codice:
    void Genera (unsigned int v[], unsigned int x, unsigned int max)
    {  /*genera x numeri casuali, inseriti in v con range da 0 a max*/
       unsigned int i = 0;
       srand ((unsigned int) time(NULL));
       for (unsigned int i = 0; i < x; i++)
          v[i] = rand()%max;
    
       for (unsigned int i = 0; i < x; i++)
          for (unsigned int j = 0; j < i; j++)
             if (v[i] == v[j])
                {
                v[i] = rand()%max;
                i = 0;
                }
    }
    
    unsigned int ContaRighe (char *Path)
    {  /*conta le righe presenti nel file*/
       ifstream file (Path, ios::in);
       if (file)
          {
          unsigned int i = 0;
          char buffer [1000];
          while (file>>buffer)
             i++;
          file.close();
          return i;
          }
       return 0;
    }
    Experience is what you get when you don’t get what you want

  6. #6
    Ti ringrazio, ho provato in bash con questo codice, ma non funge... VVoVe:
    Qualche aiuto?

    codice:
    #!/bin/bash
    # Verifica degli argomenti
    ARG=2
    E_ERR_ARG=65
    if [ $# -ne "$ARG" ]
    then
    echo "Utilizzo:  $0 file_da_leggere file_da_creare"
    exit $E_ERR_ARG
    fi
    # 
    
    fileSorg=$1
    fileDest=$2
    numRighe=4 # 1986 righe
    max=2 #264 numero di righe da leggere
    contatore=1
    
    let "casuale = (($RANDOM % $numRighe)+1)"
    
    while [ "$contatore" -le $max ]   
    do
    	if [ "${vect[$casuale]}" -ne "$casuale" ]
    		then
    			head $fileSorg -n$casuale | tail -n1 >> $fileDest
    			vect[$casuale] = $casuale
    			let "casuale = (($RANDOM % $numRighe)+1)"
            		let "contatore += 1"
            	else
            		let "casuale = (($RANDOM % $numRighe)+1)"
            		
            fi
    done


    Forse è meglio se si sposta il thread in linux, magari lì c'è qualcuno che ha più familiarità col bash?

  7. #7
    In python:

    codice:
    import random
    
    lines = []
    fin = open('file.in', 'r')
    fout = open('file.out', 'w')
    
    for line in fin.readlines():
        lines.append(line.strip())
        
    while lines:
        line_no = random.randint(0, len(lines))
        fout.write (lines.pop(line_no - 1) + '\n')
    Rilasciata Python FTP Server library 0.5.1
    http://code.google.com/p/pyftpdlib/

    We'll be those who'll make the italian folks know how difficult can be defecating in Southern California without having the crap flying all around the house.

  8. #8
    Originariamente inviato da billiejoex
    In python:

    codice:
    import random
    
    lines = []
    fin = open('file.in', 'r')
    fout = open('file.out', 'w')
    
    for line in fin.readlines():
        lines.append(line.strip())
        
    while lines:
        line_no = random.randint(0, len(lines))
        fout.write (lines.pop(line_no - 1) + '\n')
    Aspetta, mi sono perso...
    Per estrarre 264 righe tra le 1986 basta quel codice???

  9. #9
    Ah allora no, ho capito male. Quello le estrae tutte e le ripone in un secondo file in maniera casuale. Se nel primo ne hai 2000 nel secondo ne avrai 2000. Per fare come dici tu dovrebbe bastare cambiare la linea del while da:

    codice:
    while lines:
    ...a:

    codice:
    while (len(lines) != 1986 - 264):
    (non testato, fallo tu)
    Rilasciata Python FTP Server library 0.5.1
    http://code.google.com/p/pyftpdlib/

    We'll be those who'll make the italian folks know how difficult can be defecating in Southern California without having the crap flying all around the house.

  10. #10
    Grazie mille, billiejoex!
    Questo è il codice, e funziona:
    codice:
    #!/usr/bin/python
    import random
    
    lines = []
    fin = open('source.txt', 'r')
    fout = open('dest.txt', 'w')
    
    for line in fin.readlines():
        lines.append(line.strip())
        
    while (len(lines) != 1986 - 264):
        line_no = random.randint(0, len(lines))
        fout.write (lines.pop(line_no - 1) + '\n')
    Ma le righe estratte sono tutte diverse o c' è la possibilità di doppioni? Perché a me servono linee distinte tra loro...

    Puoi spiegarmi il significato di:
    while (len(lines) != 1986 - 264):
    ??

    Grazie ancora billi!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.