格式为:AAA-111
AAA
可能在哪里[A-Z][A-Z][A-Z]
并且111
可以在哪里[0-9][0-9][0-9]
问题:我们如何编写 bash 脚本来生成所有可能的变体?
答案1
正如 Chaos 所指出的,您可以使用大括号扩展来实现此目的。不过,不要忘记-
中间的内容,以使它们根据您的格式有效:
echo {A..Z}{A..Z}{A..Z}-{000..999}
如果您想要每行一个条目,您可以将其包装在一个for
循环中,例如:
for i in {A..Z}{A..Z}{A..Z}-{000..999}
do
echo "$i"
done
您可以通过> /path/to/file
在done
.
如果不想使用循环for
,也可以使用tr
使其每行打印一个条目:
echo {A..Z}{A..Z}{A..Z}-{000..999} | tr " " "\n"
另一种选择是将printf
其打印为列表。这可以为您节省一个tr
.
printf '%s\n' {A..Z}{A..Z}{A..Z}-{000..999}
答案2
答案3
为了避免使用大量内存,请使用嵌套循环。
for az1 in {A..Z}; do
for az2 in {A..Z} _; do
for az3 in {A..Z} _; do
for d1 in {0..9}; do
for d2 in {0..9}; do
printf "$az1$az2$az3-$d1$d2%i\n" {0..9}
done
done
done
done
done | sed 's/_*-0*/-/'
我添加了下划线以支持可选的较短字符串,并删除前导零,以便您可以获得类似 和 的结果A-1
以及AB-12
完整ABC-123
格式。 (检查编辑历史记录以了解如何撤消此操作。)
答案4
虽然通常您可以使用大括号扩展来创建这样的列表,但这可能太大而足以导致问题。尽管只有大约 17 M 个单词,Bash 4.4 并没有在具有 2 GB 内存的虚拟机上成功构建列表,而是在 1.5 分钟后崩溃,没有产生任何输出。
也许像 Perl 这样的东西会更好:
perl -le 'foreach $i ("AAA".."ZZZ") { foreach $j ("000".."999") { print "$i-$j" }} ; ' > plates
它会在大约 5 秒内生成列表。
如果必须在 Bash 中执行此操作,请将工作拆分为更小的循环。
不过,我确实想知道是否有更好的方法来实现您真正想要实现的目标。如果您拥有的数据不包括所有 1700 万个可能的车牌,您可能不需要将它们全部存储。如果是这样,您可能想使用 shell 之外的其他东西(即数据库)。