我有这个 bash 脚本,它生成 5 位数长的数组的每个组合:
#!/usr/bin/env bash
for combo in \
{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9}\
{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9}\
{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9}\
{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9}\
{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9};
do echo $combo;
done > output.txt
这将输出:
$ ./script.sh
aaaaa
aaaab
aaaac
...
然而,这只是冻结我的电脑。有什么办法可以将数据逐渐写入文件中吗?另外,是否可以将输出分离到不同的文件,例如每 65536 行?像输出1.txt,输出2.txt,输出3.txt?
感谢您的帮助!
答案1
如果不占用 shell 中的巨大内存,就很难生成那些大的排列。
您可以尝试其他语言,例如 Python:
$ python -c '
import itertools, string
l = [c for c in string.ascii_lowercase + string.digits]
for p in itertools.product(l, l, l, l, l): print "".join(p)
' > file
答案2
您可以使用嵌套循环,尽管它会很慢:
for p in {a..z} {0..9}
do for q in {a..z} {0..9}
do for r in {a..z} {0..9}
do for s in {a..z} {0..9}
do for t in {a..z} {0..9}
do echo $p$q$r$s$t
done
done
done
done
done | split -l 65536 --numeric-suffixes=1 --additional-suffix=.txt - output
答案3
我发现了一个很好的工具,叫做crunch
它是用 C 编写的。您还可以选择按文件大小或行分隔输出文件!
安装:$ sudo apt-get install crunch
#!/usr/bin/env bash
crunch 5 5 abcdefghijklmnopqrstuvwxyz0123456789 -o output/START -c 1048576 # Excel line limit
输出文件夹中的此命令生成的aaaaa-awrdd.txt, awrde-bi8gh.txt, bi8gi-b5pjl.txt, etc.
文件正好包含 1.048.576 行,这是 Excel 2007+ 行的限制。这也是一个超快速的解决方案。只需 10 秒即可在 58 个文件中生成 60.000.000 多个组合!完美的!
答案4
bash
在使用循环迭代之前,将始终分配 RAM 中的所有元素for
。您实际上要求bash
一次分配大量内存,而您的计算机却没有那么多内存,这就是它崩溃/冻结的原因。
这些组合本身不需要那么多(我的粗略计算给出了大约 500MB),但我认为bash
在处理数组时会产生巨大的开销。
我想知道你到底有多少可用内存。