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=B
b=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_array
my_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_importer
pf
--env my_importer
pf
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
...