多个(有一个固定的)GNU 并行参数
Multiple (with one fixed) GNU-parallel arguments
我使用 GNU-parallel 重复调用函数 foo
。该函数有两个参数,一个文件名(下面示例中的 a
,保存在数组 A
中)和一个过滤器数组(下面的 B
,以 b
作为元素B
).
该函数应该遍历 A
和 B
的所有组合,但是,要注意的是,我实际上仅使用并行来遍历 A
,同时提供 B
到每个函数调用。
举个最简单的例子:
#!/bin/bash
A=("1" "2" )
B=("X" "Y")
foo() {
a= # a single element of A
B= # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %s\n" $a $b
done
echo "-----------------"
}
export -f foo
# goal:
echo "Sequential (aka, the target) ==="
for a in "${A[@]}"; do
foo $a $B
done
结果
Sequential (aka, the target) ===
a = 1; b = X
a = 1; b = Y
-----------------
a = 2; b = X
a = 2; b = Y
-----------------
请注意,我们不是对每个组合都进行一次调用,而是对每个 A
进行一次调用,然后在函数内迭代 B
.
并行尝试:
尝试 1
parallel foo ::: "${A[@]}" ::: "${B}"
结果
a = 1; b = X
-----------------
a = 2; b = X
-----------------
(缺少 B 的第二个参数)
尝试 2
parallel foo ::: "${A[@]}" ::: "${B[@]}"
结果
a = 1; b = X
-----------------
a = 1; b = Y
-----------------
a = 2; b = X
-----------------
a = 2; b = Y
-----------------
(每个组合调用一次,而不是每个 A 调用一次,然后迭代 B)
我已经查看了手册和 SO,但找不到解决方案。
编辑
感觉直接导出数组B应该可以,但是也没有结果
foo2() {
a= # a single element of A
# B= # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %s\n" $a $b
done
echo "-----------------"
}
export -f foo2
export B
parallel foo ::: "${A[@]}"
结果
-----------------
-----------------
(显然是空B)
您的问题源于 B
是一个数组。我以前从未见过将数组作为参数传递给函数,我不确定是否可以做到。
第二个问题是,虽然您可以导出函数和变量,但您不能不作弊地导出数组:Exporting an array in bash script
GNU Parallel 使使用 env_parallel
作弊变得容易。这会将完整环境导出到 shell 运行 命令:数组、变量、别名和函数。它甚至会在 运行 远程命令时这样做。
env_parallel
去年进步很大,如果你的版本有问题请升级。
#!/bin/bash
A=("1" "2" )
B=("X" "Y")
foo() {
a= # a single element of A
# B= # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %s\n" $a $b
done
echo "-----------------"
}
# If you have earlier run 'env_parallel --install'
# to activate env_parallel in your shell
# this should work.
env_parallel foo ::: "${A[@]}"
# If you have not, then this should work:
. `which env_parallel.bash`
env_parallel foo ::: "${A[@]}"
我使用 GNU-parallel 重复调用函数 foo
。该函数有两个参数,一个文件名(下面示例中的 a
,保存在数组 A
中)和一个过滤器数组(下面的 B
,以 b
作为元素B
).
该函数应该遍历 A
和 B
的所有组合,但是,要注意的是,我实际上仅使用并行来遍历 A
,同时提供 B
到每个函数调用。
举个最简单的例子:
#!/bin/bash
A=("1" "2" )
B=("X" "Y")
foo() {
a= # a single element of A
B= # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %s\n" $a $b
done
echo "-----------------"
}
export -f foo
# goal:
echo "Sequential (aka, the target) ==="
for a in "${A[@]}"; do
foo $a $B
done
结果
Sequential (aka, the target) ===
a = 1; b = X
a = 1; b = Y
-----------------
a = 2; b = X
a = 2; b = Y
-----------------
请注意,我们不是对每个组合都进行一次调用,而是对每个 A
进行一次调用,然后在函数内迭代 B
.
并行尝试:
尝试 1
parallel foo ::: "${A[@]}" ::: "${B}"
结果
a = 1; b = X
-----------------
a = 2; b = X
-----------------
(缺少 B 的第二个参数)
尝试 2
parallel foo ::: "${A[@]}" ::: "${B[@]}"
结果
a = 1; b = X
-----------------
a = 1; b = Y
-----------------
a = 2; b = X
-----------------
a = 2; b = Y
-----------------
(每个组合调用一次,而不是每个 A 调用一次,然后迭代 B)
我已经查看了手册和 SO,但找不到解决方案。
编辑
感觉直接导出数组B应该可以,但是也没有结果
foo2() {
a= # a single element of A
# B= # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %s\n" $a $b
done
echo "-----------------"
}
export -f foo2
export B
parallel foo ::: "${A[@]}"
结果
-----------------
-----------------
(显然是空B)
您的问题源于 B
是一个数组。我以前从未见过将数组作为参数传递给函数,我不确定是否可以做到。
第二个问题是,虽然您可以导出函数和变量,但您不能不作弊地导出数组:Exporting an array in bash script
GNU Parallel 使使用 env_parallel
作弊变得容易。这会将完整环境导出到 shell 运行 命令:数组、变量、别名和函数。它甚至会在 运行 远程命令时这样做。
env_parallel
去年进步很大,如果你的版本有问题请升级。
#!/bin/bash
A=("1" "2" )
B=("X" "Y")
foo() {
a= # a single element of A
# B= # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %s\n" $a $b
done
echo "-----------------"
}
# If you have earlier run 'env_parallel --install'
# to activate env_parallel in your shell
# this should work.
env_parallel foo ::: "${A[@]}"
# If you have not, then this should work:
. `which env_parallel.bash`
env_parallel foo ::: "${A[@]}"