Bash:创建单词列表

Bash:创建单词列表

我试图输出 {a..z} 和 {0..9} 之间的所有可能组合;此输出不使用如下工具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

我们可以用正则表达式吗?我尝试了以下组合:

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

但那对我毫无帮助...

答案1

问题是这个列表很快就会变得非常大:6 个字符的所有排列以及 36(小写字母+数字):36**6=2176782336,即 2176 百万。乘以大小(6),则需要 12 GB。因此,您无法真正生成整个列表。如果您不能像在 Python 中那样使用“生成器”(根据需要生成循环值),则需要执行以下操作:

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

如果您需要更短的字符串:

#! /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

根据我的系统监视器,该代码不会显著增加 bash 进程使用的内存(根据 ,它始终大约增加 2MB,而它产生 29.5MB 的输出pv -b)。为了进行比较,以下等效代码(列表略短):

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

运行需要 600MB RAM。

做出明智的选择 :)

答案2

根据你需要的精确程度,以及可以容忍的开销,你也许可以采取类似的措施

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

你要重复{\,{A..Z},{a..z},{0..9}}每组位 - 即如果您希望每个单词最多包含 10 个字符,则您需要重复 10 次。

代码中存在一个缺陷(因为它无法识别开头的“无字符”,我使用“ ”作为占位符。这将创建重复项 - 例如“99 ”和“ 99”。您可以通过将其推送到 sort|uniq 过滤器(也可能使用 tr)来摆脱它们,但根据您的应用程序和最终输出的大小,您可能会在创建列表所需的时间上遇到困难。

要创建一个列表,输出所有不重复的排列,但与原始输入的顺序不同,您可以使用

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

相关内容