入力ファイルがありますが、名前.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[@]}"
parallel
printf '%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[@]}"