首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个(带有一个固定的)GNU并行参数

多个(带有一个固定的)GNU并行参数
EN

Stack Overflow用户
提问于 2018-01-16 06:20:13
回答 1查看 639关注 0票数 2

我使用GNU-parallel反复调用函数foo。该函数有两个参数,一个文件名(在下面的示例中是a,保存在数组A中)和一个过滤器数组(下面是B,其中bB的元素)。

该函数应该遍历AB的所有组合,然而,问题是,我实际上只使用parallel遍历A,同时为每个函数调用提供B

作为最小示例:

代码语言:javascript
复制
#!/bin/bash

A=("1" "2" )
B=("X" "Y")

foo() {
    a=$1 # a single element of A
    B=$2 # 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

结果

代码语言:javascript
复制
Sequential (aka, the target) ===
a = 1; b = X
a = 1; b = Y
-----------------
a = 2; b = X
a = 2; b = Y
-----------------

记住,对于每个组合,我们只需要对每个A调用一次,然后在函数中迭代B,而不是对每个组合进行一次调用。

并行尝试:

尝试1

代码语言:javascript
复制
parallel foo ::: "${A[@]}" ::: "${B}"

结果:

代码语言:javascript
复制
a = 1; b = X
-----------------
a = 2; b = X
-----------------

(缺少B的第二个参数)

尝试2

代码语言:javascript
复制
parallel foo ::: "${A[@]}" ::: "${B[@]}" 

结果:

代码语言:javascript
复制
a = 1; b = X
-----------------
a = 1; b = Y
-----------------
a = 2; b = X
-----------------
a = 2; b = Y
-----------------

(每个组合一个调用,而不是每个A一个调用,然后在B上迭代)

我已经看过手册了,但还是找不到解决方案。

编辑

我有一种感觉,当我直接导出数组B时,它应该可以工作,但同样没有得到任何结果

代码语言:javascript
复制
foo2() {
    a=$1 # a single element of A
    # B=$2 # 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[@]}"

结果:

代码语言:javascript
复制
-----------------
-----------------

(显然是空的B)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-16 09:23:40

您的问题源于B是一个数组。我以前从未见过将数组作为参数传递给函数,而且我不确定是否可以这样做。

第二个问题是,虽然您可以同时导出函数和变量,但不能在不作弊的情况下导出数组:Exporting an array in bash script

GNU通过使用env_parallel使作弊变得很容易。这将把完整的环境导出到运行该命令的shell中:数组、变量、别名和函数。它甚至在远程运行命令时也会这样做。

env_parallel在过去的一年中改进了很多,所以如果你的版本有问题,就升级吧。

代码语言:javascript
复制
#!/bin/bash                                                                        

A=("1" "2" )
B=("X" "Y")

foo() {
    a=$1 # a single element of A                                                   
#    B=$2 # 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[@]}"
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48271480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档