Bash 从0.00.00_aa到9.99.99_zz生成单词

Bash 从0.00.00_aa到9.99.99_zz生成单词,bash,combinations,brace-expansion,word-list,Bash,Combinations,Brace Expansion,Word List,我想通过bash脚本生成 所需的输出应如下所示: 0.00.0 0.00.00 0.00.01 ... 1.26.0 1.26.00 1.26.01 1.26.02 ... 0.00.0_a ... 0.00.0_z 0.00.00_a ... 0.00.01_a ... 9.99.99_z ... 0.00.0_aa ... 0.00.00_aa ... 1.26.99_zz ... 9.99.99_zz 我发现: printf "%03d\n" {0..999}

我想通过bash脚本生成

所需的输出应如下所示:

0.00.0    
0.00.00
0.00.01
...
1.26.0
1.26.00
1.26.01
1.26.02
...
0.00.0_a
...
0.00.0_z
0.00.00_a
...
0.00.01_a
...
9.99.99_z
...
0.00.0_aa
...
0.00.00_aa
...
1.26.99_zz
...
9.99.99_zz
我发现:

printf "%03d\n" {0..999}
但使用此脚本,输出是:

000
001
002
...
997
998
999
那么,如何修改此脚本以获得所需的输出?

连接多个大括号展开以构建其笛卡尔乘积。也就是说,要生成
0001。。。99
您可以编写
{0..9}{0..9}
。自Bash4.0以来,您还可以编写
{00..99}
。这只适用于数字。对于字母,您仍然必须编写
{a..z}{a..z}

对于
0 00 01 02中的单个
0
。。。99
可以像这样嵌套大括号扩展:
{0,{00..99}
。对于使用空字符串的丢失字母也是如此:
{,{a..z}


警告:以下命令占用大量内存。磁盘上的输出可能“仅”约为750MB,但运行的bash进程使用了超过16GB的内存。如果内存/交换不足,则命令可能会被终止(如果幸运的话),或者系统冻结,需要您执行硬重启

有关更好的解决方案,请参见此答案的结尾


现在让我们把所有的东西放在一起:

printf %s\\n {0..9}.{00..99}.{0,{00..99}}{,_{,{a..z}}{a..z}} > outputFile
这个大括号扩展生成71'003'000行,将它们打印到标准输出需要花费一些时间,因此我们将输出重定向到文件
outputFile
。通过运行
grep-Fxf exampleAsAFile outputFile
,您可以确认这至少生成了示例中的行。或者,运行此简化命令,将
0..9
替换为
0..1
,将
a..z
替换为
a..b
,然后手动检查结果:

printf %s\\n {0..1}.{0..1}{0..1}.{0,{0..1}{0..1}}{,_{,{a..b}}{a..b}}
尽管我们刚刚生成了所有必需的行,但顺序与您的示例不同。要调整顺序,可以通过
排序运行结果,但这将浪费资源。相反,您可以使用多个大括号展开,以便按正确的顺序生成所有内容:

printf %s\\n \
  {0..9}.{00..99}.{0,{00..99}} \
  {0..9}.{00..99}.{0,{00..99}}_{a..z} \
  {0..9}.{00..99}.{0,{00..99}}_{a..z}{a..z} \
  > outputFile
减少内存占用 为了减少内存占用,可以将前缀拆分为
for
循环。具体在哪里拆分取决于您的偏好和系统。循环中的括号越少,意味着内存越多,但执行速度越快(只要内存足够)。循环中的大括号越多,意味着执行速度越慢,但内存越少(只要前缀的长度短于大括号扩展的一半;使其变长只会产生负面影响)


可以使用3个大括号展开。(1) [程式码>印刷公司的「代码>印刷公司的[程式码>印刷公司的[程式码>印刷公司的[程式码>印刷公司的[程式码>印刷公司的[程式码>印刷公司的[码码>印刷公司的[码码码>s\n{0.0 0 0.00.00<码>0.0\n{0.0.0.9}{{0.0.9}{n{0.0.0.0.9}n{n{0.0.0.0.0.0.............n{0 0.....0.......0.....0....0.....0....0.....0......0......0...0.0.0...0.0.0.0..0.0.0.0.0...{0..9}.{0..9}{0..9}.{0..9}{0..9}{a..z}{a..z}
。总数将是数万或数十万个排列。@David C.Rankin,好的,谢谢。但是我如何也得到输出0.00.0呢?例如:0.00.0、0.00.00、0.00.01。。。如果我尝试使用
printf“%s\n”{0..9}.{0..9}{0..9}.{0..9}{0..9}
,我遗漏了0.00.0变量,因此我遗漏了带有一个零的变量。在您的示例中,不清楚要在哪里使用单位数。在您的评论中,您编写了示例中未出现的
0.00.0
。在那里,我本以为这是第一行。你们能回答你们的问题吗?这样你们就可以更清楚地知道你们想要个位数了吗?@Socowi,为了得到更合适的结果,我已经编辑了这个例子
# use only if order doesn't matter. 
# takes 1m30s and 24 MB of memory
for prefix in {0..9}.{00..99}; do
    printf "$prefix.%s\n" {0,{00..99}}{,_{,{a..z}}{a..z}}
done > outputFile
# takes 2m and 24 MB of memory
for prefix in {0..9}.{00..99}; do
  printf "$prefix.%s\n" {0,{00..99}} >> part1
  printf "$prefix.%s\n" {0,{00..99}}_{a..z} >> part2
  printf "$prefix.%s\n" {0,{00..99}}_{a..z}{a..z} >> part3
done
cat part{1..3} > outputFile