使用 bash 生成排列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3846123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generating permutations using bash
提问by siliconpi
is it possible to write a bash script that can read in each line from a file and generate permutations (without repetition) for each? Using awk / perl is fine.
是否可以编写一个 bash 脚本,该脚本可以从文件中读取每一行并为每一行生成排列(不重复)?使用 awk / perl 很好。
File
----
ab
abc
Output
------
ab
ba
abc
acb
bac
bca
cab
cba
回答by jlonganecker
I know I am a little late to the game but why not brace expansion?
我知道我玩游戏有点晚了,但为什么不扩展支架呢?
For example:
例如:
echo {a..z}{0..9}
Outputs:
输出:
a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 g0 g1 g2 g3 g4 g5 g6 g7 g8 g9 h0 h1 h2 h3 h4 h5 h6 h7 h8 h9 i0 i1 i2 i3 i4 i5 i6 i7 i8 i9 j0 j1 j2 j3 j4 j5 j6 j7 j8 j9 k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 l0 l1 l2 l3 l4 l5 l6 l7 l8 l9 m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 n0 n1 n2 n3 n4 n5 n6 n7 n8 n9 o0 o1 o2 o3 o4 o5 o6 o7 o8 o9 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 u0 u1 u2 u3 u4 u5 u6 u7 u8 u9 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 w0 w1 w2 w3 w4 w5 w6 w7 w8 w9 x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 y0 y1 y2 y3 y4 y5 y6 y7 y8 y9 z0 z1 z2 z3 z4 z5 z6 z7 z8 z9
Another useful example:
另一个有用的例子:
for X in {a..z}{a..z}{0..9}{0..9}{0..9}
do echo $X;
done
回答by livibetter
Pure bash (using local
, faster, but can't beat the other answer using awk below, or the Python below):
纯 bash(使用local
,更快,但无法使用下面的 awk 或下面的 Python 击败其他答案):
perm() {
local items=""
local out=""
local i
[[ "$items" == "" ]] && echo "$out" && return
for (( i=0; i<${#items}; i++ )) ; do
perm "${items:0:i}${items:i+1}" "$out${items:i:1}"
done
}
while read line ; do perm $line ; done < File
Pure bash (using subshell, much slower):
纯 bash(使用子shell,慢得多):
perm() {
items=""
out=""
[[ "$items" == "" ]] && echo "$out" && return
for (( i=0; i<${#items}; i++ )) ; do
( perm "${items:0:i}${items:i+1}" "$out${items:i:1}" )
done
}
while read line ; do perm $line ; done < File
Since asker mentioned Perl is fine, I think Python 2.6+/3.X is fine, too:
由于提问者提到 Perl 很好,我认为 Python 2.6+/3.X 也很好:
python -c "from itertools import permutations as p ; print('\n'.join([''.join(item) for line in open('File') for item in p(line[:-1])]))"
For Python 2.5+/3.X:
对于 Python 2.5+/3.X:
#!/usr/bin/python2.5
# http://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list-in-python/104436#104436
def all_perms(str):
if len(str) <=1:
yield str
else:
for perm in all_perms(str[1:]):
for i in range(len(perm)+1):
#nb str[0:1] works in both string and list contexts
yield perm[:i] + str[0:1] + perm[i:]
print('\n'.join([''.join(item) for line in open('File') for item in all_perms(line[:-1])]))
On my computer using a bigger test file:
在我的计算机上使用更大的测试文件:
First Python code
Python 2.6: 0.038s
Python 3.1: 0.052s
Second Python code
Python 2.5/2.6: 0.055s
Python 3.1: 0.072s
awk: 0.332s
Bash (local): 2.058s
Bash (subshell): 22+s
回答by ghostdog74
A faster version using awk
使用 awk 的更快版本
function permute(s, st, i, j, n, tmp) {
n = split(s, item,//)
if (st > n) { print s; return }
for (i=st; i<=n; i++) {
if (i != st) {
tmp = item[st]; item[st] = item[i]; item[i] = tmp
nextstr = item[1]
for (j=2; j<=n; j++) nextstr = nextstr delim item[j]
}else {
nextstr = s
}
permute(nextstr, st+1)
n = split(s, item, //)
}
}
{ permute($ awk -f permute.awk file
,1) }
usage:
用法:
while read a; do crunch 0 0 -p "$a"; done 2> /dev/null < File
回答by jyz
Using the crunch
util, and bash
:
使用crunch
util 和bash
:
ab
ba
abc
acb
bac
bca
cab
cba
Output:
输出:
#!/bin/bash
list=`echo {0..9} {a..z} {A..Z}`
for c1 in $list
do
for c2 in $list
do
for c3 in $list
do
echo $c1$c2$c3
done
done
done
Tutorial here https://pentestlab.blog/2012/07/12/creating-wordlists-with-crunch/
教程在这里https://pentestlab.blog/2012/07/12/creating-wordlists-with-crunch/
回答by Brian Agnew
See the Perl Cookbookfor permutation examples. They're word/number oriented but a simple split()
/join()
on your above example will suffice.
有关排列示例,请参阅Perl Cookbook。它们是面向单词/数字的,但是上面示例中的简单split()
/join()
就足够了。
回答by gsbabil
Bash word-list/dictionary/permutation generator:
Bash 单词列表/字典/排列生成器:
The following Bash code generates 3 character permutation over 0-9, a-z, A-Z. It gives you (10+26+26)^3 = 238,328 words in output.
以下 Bash 代码在 0-9、az、AZ 上生成 3 个字符排列。它在输出中为您提供 (10+26+26)^3 = 238,328 个单词。
It's not very scalable as you can see you need to increase the number of for
loop to increase characters in combination. It would be much faster to write such thing in assembly or C using recursion to increase speed. The Bash code is only for demonstration.
它的可扩展性不是很好,因为您可以看到您需要增加for
循环次数以增加组合字符。在汇编或 C 中使用递归来提高速度会更快。Bash 代码仅用于演示。
P.S.You can populate $list
variable with list=$(cat input.txt)
PS您可以填充$list
变量list=$(cat input.txt)
000
001
002
003
004
005
...
...
...
ZZU
ZZV
ZZW
ZZX
ZZY
ZZZ
[babil@quad[13:27:37][~]> wc -l t.out
238328 t.out
SAMPLE OUTPUT:
样品输出:
$ ruby -ne '$_.chomp.chars.to_a.permutation{|x| puts x.join}' file # ver 1.9.1
回答by ghostdog74
while read s;do p="$(echo "$s"|sed -e 's/./&,/g' -e 's/,$//')";eval "printf "%s\\n" "$(eval 'echo "$(printf "{'"$p"'}%.0s" {0..'"$((${#s}-1))"'})"')"|grep '\(.\)*.*' -v";echo;done <f
回答by Michael Krupp
Because you can never have enogh cryptic Bash-oneliners:
因为你永远不可能有 enogh 神秘的 Bash-oneliners:
$ time while read s;do p="$(echo "$s"|sed -e 's/./&,/g' -e 's/,$//')";eval "printf "%s\\n" "$(eval 'echo "$(printf "{'"$p"'}%.0s" {0..'"$((${#s}-1))"'})"')"|grep '\(.\)*.*' -v";echo;done <f >/dev/null
real 0m0.021s
user 0m0.000s
sys 0m0.004s
It's pretty fast - at least on my machine here:
它非常快 - 至少在我的机器上:
##代码##But be aware that this one will eat a lot of memory when you go beyond 8 characters...
但是请注意,当您超过 8 个字符时,这个会占用大量内存......