使用 gnu parallel 迭代数组元素

使用 gnu parallel 迭代数组元素

我有一个输入文件,姓名.txt,每行 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,但它太慢了(我的实际数据文件大约有 200k 行)。这就是为什么我想使用数组元素并gnu parallel同时加速该过程。
我尝试了不同的方法来访问parallel ' '命令中的数组元素(主要通过修改此循环 - for word in "${line[@]}",或通过将数组提供给parallelvia 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 可以生成输入源的所有组合。

在你的情况下,你只需使用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[@]}"

相关内容