GNUパラレル - 配列の2つのパラメータを引数として使用する

GNUパラレル - 配列の2つのパラメータを引数として使用する

Gnu並列性を使用するスクリプトがあります。各「繰り返し」ごとに2つのパラメータを渡したいと思います。

シリアル実行には次のものがあります。

for (( i=0; i<=10; i++ ))
do
  a = tmp1[$i]
  b = tmp2[$i]
done

並列化したいです。

func pf()
{
   a=$1
   b=$2
}
export -f pf
parallel --jobs 5 --linebuffer pf ::: <what to write here?>

答え1

集中を維持するために他のparallelフラグを省略しています...

parallel --link pf ::: A B ::: C D

まず、次のようにa=A関数をb=C実行します。a=Bb=D

a=A b=C
a=B b=D

それ以外の場合は、--link次のような完全な組み合わせを得ることができます。

a=A b=C
a=A b=D
a=B b=C
a=B b=D

修正する:Ole Tangeがコメントで述べたように、[削除済み -エド。]これを行うもう1つの方法があります::::+演算子を使用することです。ただし、これら2つのオプションには重要な違いがあります。もしパラメーター位置ごとにパラメーター数が同じではありません。説明するために例を見てください。

parallel --link pf ::: A B ::: C D E出力:

a=A b=C
a=B b=D
a=A b=E

parallel pf ::: A B :::+ C D E出力:

a=A b=C
a=B b=D

したがって、--linkすべてのパラメータが消費されるように「ラップ」され、:::+追加のパラメータは無視されます。 (通常の場合、--link代替は自動的に入力を無視することですので、私はそれを好みます。YMMV。)

答え2

単純化するために、bashを想定し、配列のインデックスはゼロではなく1から指定されます。次のようなことを行うのは直感的なようです。

parallel ... pf '$tmp1[{#}]' '$tmp2[{#}]' ::: $(seq 10)

関数の2つのパラメーターがpfコマンドの一部である場合は、並列表記を使用してジョブ番号を表します(10ジョブの場合は1から10に設定)。後で10個のジョブを実行するには、10個のパラメータを取得する{#}だけです(seq値は使用されず、ジョブ番号と同じになります)。seq:::

残念ながら、bashは配列変数をエクスポートしないため、機能しません。ただし、関数をエクスポートすることができ、マニュアルページには、選択した関数をエクスポートまたはインポートするparallel単純な関数を使用して選択した配列変数を設定する解決策が記載されています。import_arraymy_importer

declare -a tmp1 tmp2
for (( i=1; i<=10; i++ ))
do tmp1[$i]=x$i
   tmp2[$i]=y$i
done

import_array(){
    local func=$1; shift;
    export $func='() {
      '"$(for arr in $@; do
            declare -p $arr|sed '1s/declare -./&g/'
          done)"'
    }'
}
import_array my_importer tmp1 tmp2

オプションを使用してコマンド環境に関数を渡し、parallel実行する前に関数を実行します。my_importerpf--env my_importerpf

pf(){ a=$1; b=$2; echo "job a=$a b=$b"; }
export -f pf 

parallel -v --jobs 5 --linebuffer \
 --env my_importer 'my_importer;'  pf '${tmp1[{#}]}' '${tmp2[{#}]}' ::: $(seq 10)

結果の出力は-v次のようになります。

my_importer; pf ${tmp1[2]} ${tmp2[2]}
my_importer; pf ${tmp1[1]} ${tmp2[1]}
my_importer; pf ${tmp1[5]} ${tmp2[5]}
my_importer; pf ${tmp1[3]} ${tmp2[3]}
job a=x1 b=y1
my_importer; pf ${tmp1[6]} ${tmp2[6]}
job a=x2 b=y2
my_importer; pf ${tmp1[7]} ${tmp2[7]}
job a=x4 b=y4
...

関連情報