bash 中多个 `seq` 的外积

Outer product from multiple `seq`s in bash

来自3个序列(例如): seq 0 0.2 1, seq 0 0.3 1.5, seq 0 0.5 1 我想生成类似的东西 0:0:0 0:0:0.5 0:0:1 0:0.3:0 0:0.3:0.5 0:0.3:1...。它们采用 a:b:c 格式,其中 a 来自第一个序列,b 来自第二个序列,c 来自第三个序列,所有组合都出现一次。

如果这些是整数并且具有统一步长,我可以使用 {1..10}:{2..10}:{3..10},并且它工作得很好,但是无论如何可以将这个大括号函数扩展到非整数和非统一步长吗?

非常感谢!

老实说,对于这项工作,awk 是比 seq 更好的工具;它是 POSIX 标准化的,在 I/O 时比 bash 快得多,而且您可以 运行 只有一个实例来生成所有输出:

awk '
BEGIN {
  for(a=0; a<=1; a+=0.2) {
    for(b=0; b<=1.5; b+=0.2) {
      for(c=0; c<=1; c+=0.5) {
        printf("%.1f:%.1f:%.1f\n", a, b, c);
      }
    }
  }
}' </dev/null

但是,如果出于某种原因您真的想要使用seq,嵌套三个BashFAQ #1 while read循环将完成这项工作:

#!/usr/bin/env bash
while read -r a; do
  while read -r b; do
    while read -r c; do
      printf '%.1f:%.1f:%.1f\n' "$a" "$b" "$c"
    done < <(seq 0 0.5 1)
  done < <(seq 0 0.3 1.5)
done < <(seq 0 0.2 1)

在我的系统上,seq 版本 运行s 在 ~0.3 秒挂钟,而 awk 版本需要 ~0.01s。

这可能适合您(GNU sed 和并行):

parallel echo ::: $(seq 0 0.2 1) ::: $(seq 0 0.3 1.5) ::: $(seq 0 0.5 1) |
sed -z 'y/ \n/: /;s/\.0//g'

另一种方法,使用 bash 和 sed:

echo {00..10..2}:{00..15..3}:{00..10..5} | sed 's/\B/./g;s/\.0//g'