Hinweis: Das Forum wird geschlossen! Neue Registrierungen sind nicht mehr möglich!

 Zurück zu Pro-Linux   Foren-Übersicht   FAQ     Suchen    Mitgliederliste
bash: Zufällige Elemente aus einer Liste

 
Neuen Beitrag schreiben   Auf Beitrag antworten    Pro-Linux Foren-Übersicht -> Programmieren - Allgemein
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Rudni
Gast





BeitragVerfasst am: 04. Feb 2010 18:02   Titel: bash: Zufällige Elemente aus einer Liste

Hallo,

Aus einer rein aus Zahlen bestehenden Liste (sagen wir durchnummeriert von 0001 - 1000) würde ich gerne 10% der Elemente zufällig auswählen, also in diesem Beispiel 100 eindeutige Namen, die in diesem Bereich liegen.

Geht das?
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 04. Feb 2010 18:50   Titel:

Klar geht das. Nur ist es nicht besonders simpel, gerade in bash. Gibt es einen Grund, sowas ausgerechnet in bash machen zu wollen?

Grundsätzliches vorgehen: Zwei Listen, Quellliste, am Anfang voll, Zielliste, am Anfang leer. Ein zufälliges Element aus der Quellliste rauspicken, dort entfernen, in die Zielliste eintragen.
100 mal wiederholen.

In Tcl wär das z.B. wie folgt zu machen:
Code:

#!/usr/bin/tclsh

set q {1 2 3 4 5 6 7 8 9 10 11 12 13}
set z {}

for {set c 0} {$c<5} {incr c} {
  set i [expr int(rand()*[llength $q])]
  lappend z [lindex $q $i]
  set q [lreplace $q $i $i]
}

puts $z

Mit bash musst du die notwendigen Stringoperationen llength, lindex und lreplace selbst schreiben.

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

Rudni
Gast





BeitragVerfasst am: 04. Feb 2010 20:03   Titel:

Ja, es gibt einen Grund. Das gesamte Skript ist alles bash, denn das ist das Einzige, was ich zumindest minimal kann, dies ist nur ein Auszug. Ich wüßte auch nicht, wie ich tcl in bash einbinden kann.

Bei der bash scheitere ich an den Schleifen, um auf Duplikate zu überprüfen. Ach, wie wünschte ich mir gerade goto & Zeilennummern zurück...


Trotzdem vielen Dank für Deine Mühe
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 04. Feb 2010 20:51   Titel:

Dann nimm doch einfach das Skript oben. Die Syntax der tclsh ist so schwierig nicht. Wenn du mir genau sagst was du haben willst, puste ich dir das Skript auch gerne noch ein wenig auf.

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

Rudni
Gast





BeitragVerfasst am: 04. Feb 2010 21:18   Titel:

Vielen Dank erstmal,

vielleicht komme ich darauf sogar zurück. Aber mit Chance habe ich auch eine bash Lösung gefunden, kann ich aber erst morgen testen:

Code:

FILES=10000000
LANGE=`echo ${#FILES}`
FAKTOR=2000000
NOADD=0
WERT=`echo $((${RANDOM}%${FILES}))`
DELETE=`echo ${WERT}`
ZAEHLER=1

while [ ${ZAEHLER} -le ${FAKTOR} ]; do
   WERT=`echo $((${RANDOM}%${FILES}))`
   for Y in ${DELETE}; do
      if [ "${Y}" == "${WERT}" ]; then     
         NOADD=1
         break
      fi
   done
   if [ ! "${NOADD}" == "1" ]; then
      WERT=`printf "%0${LANGE}d\n" ${WERT}`
      DELETE=`echo -n ${DELETE} echo -n ${WERT}`
      let ZAEHLER+=1
   fi
   NOADD=0
done


Gut, etwas umständlich und rechenaufwendig bei geschätzen 10 000 000 Dateien, aber wofür haben wir GHz Prozessoren?
 

Rudni
Gast





BeitragVerfasst am: 05. Feb 2010 16:49   Titel: ONL73O

Viel Einfacher:
Code:

ls | sort --random-sort | head -n 2000
 

Janka



Anmeldungsdatum: 11.02.2006
Beiträge: 3569

BeitragVerfasst am: 05. Feb 2010 20:19   Titel:

Und schnell, wie praktisch! Danke fürs Posten dieser Lösung.

Janka
_________________
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
 
Benutzer-Profile anzeigen Private Nachricht senden

komsomolze



Anmeldungsdatum: 03.03.2006
Beiträge: 429

BeitragVerfasst am: 13. Feb 2010 23:43   Titel:

Rudnis Lösung ist ja klasse.



Hier noch ein bischen bash-random.
In /etc/cron.daily/apt :
Code:

random_sleep()
{
    RandomSleep=1800
    eval $(apt-config shell RandomSleep APT::Periodic::RandomSleep)
    if [ $RandomSleep -eq 0 ]; then
        return
    fi
    if [ -z "$RANDOM" ] ; then
        # A fix for shells that do not have this bash feature.
        RANDOM=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -c"1-5")
    fi
    TIME=$(($RANDOM % $RandomSleep))
    debug_echo "sleeping for $TIME seconds"
    sleep $TIME
}
darin der operative Teil:
Code:
    RandomSleep=1800
    if [ -z "$RANDOM" ] ; then
        # A fix for shells that do not have this bash feature.
        RANDOM=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -c"1-5")
    fi
    TIME=$(($RANDOM % $RandomSleep))

Und die Anmerkung darin führt zu:
Code:

$ echo $RANDOM
29640
$ echo $RANDOM
1890
$ echo $RANDOM
13575

_________________
mfg komsomolze
 
Benutzer-Profile anzeigen Private Nachricht senden

Beiträge vom vorherigen Thema anzeigen:   
     Pro-Linux Foren-Übersicht -> Programmieren - Allgemein Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehen Sie zu:  

Powered by phpBB © phpBB Group
pro_linux Theme © 2004 by Mandaxy