Bash: Wortlisten erstellen

0

Ich versuche, jede mögliche Kombination zwischen {a..z} und {0..9} auszugeben. diese Ausgabe ohne Verwendung von Werkzeugen wie crunch:

$ head wordlist.txt

a
b
c
1
2
3
aa
ab
ac
a1

$ tail wordlist.txt

333332c
3333321
3333322
3333323
333333a
333333b
333333c
3333331
3333332
3333333

Können wir mit Regex machen? Ich habe versucht, Kombinationen von Dingen wie:

for i in $(<magic here>); do
  echo "$i"
done

Aber das brachte mich nirgendwo hin ...

user809474
quelle

Antworten:

1

Das Problem ist, dass dies ziemlich schnell riesig wird: Alle Permutationen von 6 Zeichen entlang 36 (Kleinbuchstaben + Ziffern): 36 ** 6 = 2176782336, das sind 2176 Millionen. Multiplizieren Sie mit der Größe (6) und Sie benötigen 12 Gigabyte. Sie können also nicht wirklich die gesamte Liste generieren. Wenn Sie keine "Generatoren" wie in Python verwenden können (die Schleifenwerte nach Bedarf generieren), müssen Sie Folgendes tun:

for t1 in $chars; do 
    for t2 in $chars; do 
        for t3 in $chars; do 
            for t4 in $chars; do 
                for t5 in $chars; do
                    echo $t1$t2$t3$t4$t5
                done
            done
        done
    done
done

Wenn Sie die kürzeren Saiten brauchen:

#! /bin/bash

chars=('' a b c)

for t1 in "${chars[@]}"; do 
    for t2 in "${chars[@]}"; do 
        for t3 in "${chars[@]}"; do
            echo $t1$t2$t3
        done
    done
done

Laut meinem Systemmonitor erhöht der Code den vom Bash-Prozess verwendeten Speicher nicht wesentlich (ungefähr 2 MB, während er 29,5 MB der Ausgabe entsprechend erzeugt pv -b). Zum Vergleich dieser äquivalente Code (mit etwas kürzeren Listen):

for t in {a..t}{a..t}{a..t}{a..t}{a..t} ; do 
    echo $t
done

Benötigt 600 MB RAM zum Ausführen.

Wähle mit Bedacht :)

Magnet
quelle
xenoid - hast du mich abgelehnt? Auch Ihre Antwort behandelt nicht Fälle von "a", "aa" usw.
Davidgo
Nein, ich habe nichts abgewertet ... Die Lösung für die Ausgabe der kürzeren Zeichenfolgen wurde aktualisiert ...
Xenoid
0

Je nachdem, wie genau Sie dies tun müssen und wie hoch der erträgliche Aufwand ist, können Sie möglicherweise mit so etwas davonkommen

echo {\ ,{A..Z},{a..z},{0..9}}{\ ,{A..Z},{a..z},{0..9}}{\ ,{A..Z},{a..z},{0..9}}

Wo Sie das Bit {\, ​​{A..Z}, {a..z}, {0..9}} für jede Menge wiederholen würden - dh wenn Sie möchten, dass jedes Wort maximal 10 Zeichen enthält, würden Sie dies tun wiederhole es 10 mal.

Der Code weist einen Fehler auf (da er am Anfang kein "kein Zeichen" erkennt, habe ich "" als Platzhalter verwendet. Dadurch werden Duplikate erstellt - dh "99" und "99". Möglicherweise Entfernen Sie diese, indem Sie es durch einen sort | uniq-Filter schieben (und möglicherweise auch tr verwenden). Abhängig von Ihrer Anwendung und der Größe der endgültigen Ausgabe kann es jedoch schwierig sein, die Liste zu erstellen.

Um eine Liste zu erstellen, die alle Permutationen ohne Duplikate ausgibt, aber in einer anderen Reihenfolge als die ursprüngliche Eingabe, die Sie verwenden könnten

for each in {\ ,{A..Z},{a..z},{0..9}}{\ ,{A..Z},{a..z},{0..9}}{\ ,{A..Z},{a..z},{0..9}} ; do  echo $each; done | tr -d " " | sort -u
Davidgo
quelle