私は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?>
集中するために他の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
pdate: Ole Tangeがコメントで言及したように[削除されたため-Ed。]これを行う別の方法があります:使用:::+
演算子。ただし、2つの選択肢には重要な違いがありますif引数の数は各param位置で同じではありません。例を示します。
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。)
簡単にするために、bashを想定し、配列には0ではなく1からインデックスが付けられていると仮定します。
parallel ... pf '$tmp1[{#}]' '$tmp2[{#}]' ::: $(seq 10)
ここで、pf
関数への2つの引数はコマンドの一部であり、並列表記{#}
を使用してジョブ番号を表します(10個のジョブでは1から10に設定されています。 seq
を使用して:::
の後に10個の引数を取得し、10個のジョブを実行するようにします(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
...