Gnuパラレルを使用した配列要素の反復

Gnuパラレルを使用した配列要素の反復

入力ファイルがありますが、名前.txt、1行に1単語:

apple  
abble  
aplle 

私のbashスクリプトで次のような出力を取得しようとしています。

apple and apple  
apple and abble  
apple and aplle  
abble and apple  
abble and abble  
abble and aplle  
aplle and apple  
aplle and abble  
aplle and aplle

これは私のbashスクリプトです。

#!/usr/bin bash
readarray -t seqcol < names.txt

joiner () {
           val1=$1
           val2=$2
           echo "$val1 and $val2"
}

export -f joiner

parallel -j 20 '
    line=($(echo {}))
    for word in "${line[@]}"; do
            joiner "${line}" "${word}"
    done
' ::: "${seqcol[@]}"

しかし、配列の同じ要素を比較して、次の3行だけを出力します。

apple and apple  
abble and abble  
aplle and aplle

ループを使用するスクリプトがありますが、遅すぎますwhile read line(実際のデータファイルは約200,000行です)。だから、配列要素を使用しながらgnu parallel同時にプロセスをスピードアップしたいと思います。コマンドは配列要素に
アクセスするさまざまな方法を試しましたが(主にこのループを修正するか、viaに配列を供給することによって)エラーが発生したり、空白行が出力されます。parallel ' 'for word in "${line[@]}"parallelprintf '%s\n' "${seqcol[@]}"

助けてくれてありがとう!

答え1

parallel正しい出力順序が必ずしも維持されるわけではありません。

とにかくパフォーマンスに興味がある場合は、bashテキストファイルを使用しないでください。代わりに、awk.または.などのプログラミング言語などの特別なツールを使用してくださいpython

awk '
  { words[NR]=$0 }
  END {
    for (x in words){
      for (y in words) { printf "%s and %s\n",words[x],words[y] }
    }
  }' file

答え2

GNU Parallelは任意の入力ソースの組み合わせを生成できます。

あなたの場合は2回だけ使用してくださいnames.txt

parallel -k echo {1} and {2} :::: names.txt names.txt

または(配列がある場合):

readarray -t seqcol < names.txt
parallel -kj 20 echo {1} and {2} ::: "${seqcol[@]}" ::: "${seqcol[@]}"

関連情報