生成从 0.00.00_aa 到 9.99.99_zz 的单词
Generating words from 0.00.00_aa to 9.99.99_zz
我想通过 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
那么,如何修改此脚本以获得我想要的输出?
连接 多个大括号扩展以构建其笛卡尔积。也就是说,要生成 00 01 ... 99
你可以写 {0..9}{0..9}
。从 bash 4.0 开始你也可以写 {00..99}
。这仅适用于数字。对于字母,您仍然必须写 {a..z}{a..z}
.
对于 0 00 01 02 ... 99
中的单个 0
,您可以 嵌套 大括号扩展,如下所示:{0,{00..99}}
。对于我们使用空字符串的缺失字母也是如此:{,{a..z}}
.
警告:以下命令占用大量内存。磁盘上的输出可能“仅”约 750 MB,但 运行ning bash 进程为我使用了 超过 16 GB 的内存。如果你没有足够的 memory/swap 命令可能会被杀死(如果你幸运的话)或者你的 系统冻结 ,需要你做一个 硬重启 .
要获得更好的解决方案,请参阅此答案的结尾。
现在让我们把所有东西放在一起:
printf %s\n {0..9}.{00..99}.{0,{00..99}}{,_{,{a..z}}{a..z}} > outputFile
这个大括号扩展生成 71'003'000 行,将它们打印到标准输出需要很长时间,因此我们将输出重定向到文件 outputFile
。您可以通过 运行ning 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}}
尽管我们刚刚生成了所有必需的行,但顺序与您的示例不同。要调整顺序,您可以通过 Schwartzian transform sort
运行 结果,但这会浪费资源。相反,您可以使用多个大括号扩展,以便以正确的顺序生成所有内容:
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
循环。具体在哪里拆分取决于您的偏好和系统。循环中更少的大括号意味着更多的内存但执行速度更快(只要你有足够的内存)。循环中更多的大括号意味着执行速度更慢但内存更少(只要前缀短于大括号扩展的一半;使其更长只会产生负面影响)。
# 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
我想通过 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
那么,如何修改此脚本以获得我想要的输出?
连接 多个大括号扩展以构建其笛卡尔积。也就是说,要生成 00 01 ... 99
你可以写 {0..9}{0..9}
。从 bash 4.0 开始你也可以写 {00..99}
。这仅适用于数字。对于字母,您仍然必须写 {a..z}{a..z}
.
对于 0 00 01 02 ... 99
中的单个 0
,您可以 嵌套 大括号扩展,如下所示:{0,{00..99}}
。对于我们使用空字符串的缺失字母也是如此:{,{a..z}}
.
警告:以下命令占用大量内存。磁盘上的输出可能“仅”约 750 MB,但 运行ning bash 进程为我使用了 超过 16 GB 的内存。如果你没有足够的 memory/swap 命令可能会被杀死(如果你幸运的话)或者你的 系统冻结 ,需要你做一个 硬重启 .
要获得更好的解决方案,请参阅此答案的结尾。
现在让我们把所有东西放在一起:
printf %s\n {0..9}.{00..99}.{0,{00..99}}{,_{,{a..z}}{a..z}} > outputFile
这个大括号扩展生成 71'003'000 行,将它们打印到标准输出需要很长时间,因此我们将输出重定向到文件 outputFile
。您可以通过 运行ning 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}}
尽管我们刚刚生成了所有必需的行,但顺序与您的示例不同。要调整顺序,您可以通过 Schwartzian transform sort
运行 结果,但这会浪费资源。相反,您可以使用多个大括号扩展,以便以正确的顺序生成所有内容:
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
循环。具体在哪里拆分取决于您的偏好和系统。循环中更少的大括号意味着更多的内存但执行速度更快(只要你有足够的内存)。循环中更多的大括号意味着执行速度更慢但内存更少(只要前缀短于大括号扩展的一半;使其更长只会产生负面影响)。
# 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