【问题标题】:Increase the amount of brace expansions given a number在给定数字的情况下增加大括号扩展的数量
【发布时间】:2018-08-21 15:09:45
【问题描述】:

我有一个使用大括号扩展的程序:

for X in {a..z}
    do echo $X;
done

我想用提供的数字增加大括号扩展中使用的字母数量。例如,如果提供了数字 3:

for X in {a..z}{a..z}{a..z}
    do echo $X;
done

如果提供数字 5:

for X in {a..z}{a..z}{a..z}{a..z}{a..z}
    do echo $X;
done

如何在 bash 中做到这一点?

【问题讨论】:

  • 你不能,而且你几乎肯定不想这样做。表达式立即展开,然后开始迭代。 {a..z}{a..z}{a..z}{a..z}{a..z}首先在内存中扩展到近1200万个字符串;它不是一个惰性生成器。
  • 替代方案:使用嵌套的 for 循环。将您当前拥有的 for 循环嵌套在另一个或两个循环下。
  • 你只是想生成所有可能的 n 个字母组合,还是真的想用这个来做其他事情?
  • @AlexM 我正在​​制作一个小蛮力来取乐,这将允许我获得一组特定字母的所有排列
  • 这在 Python 中可能会更容易,使用 itertools.permutationsstring.ascii_lowercase

标签: bash brace-expansion


【解决方案1】:

这是一种方法。与a..z

$ a2z() { 
  k=""
  n=$1
  while [ $n -gt 0 ]
  do
    k="{a..z}$k"
    let n="$n-1"
  done
  echo $(eval "echo $k")
}
$ for X in $(a2z 3)
do echo $X;
done
aaa
aab
aac
...

使用0..1 有点有用,或者至少很有趣,因为它显示了 N 位的每个排列。

$ bitperms() {
  k=""
  n=$1
  while [ $n -gt 0 ] 
  do
    k="{0..1}$k"
    let n="$n-1"
  done
  echo $(eval "echo $k")
}
$ bitperms 4
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
$ for X in $(bitperms 2);do echo "$X";done
00
01
10
11

【讨论】:

  • 而且,正如@chepner 提到的 - 这会很快杀死你的系统。
  • 是的,我知道它会杀死系统,只是为了好玩而已
  • 顺便说一句,我建议eval "echo $k",只是为了更明确地了解幕后发生的事情(并明确eval实际上在单个字符串上运行)。对于这个用例来说无关紧要,但是还有很多其他场景,让eval string-split 和 glob-expand 其各个参数,然后将它们连接在一起以生成该字符串(然后对其进行解析)会导致错误。
  • 完成 - 那行的引号让我感到困惑。我不认为echo "$(eval "echo $k")" 会正常工作(确实如此),所以我最终把所有引号都去掉了。
猜你喜欢
  • 2022-11-12
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多