在 GNU 并行中使用变量作为输入

在 GNU 并行中使用变量作为输入

我想使用变量作为输入,同时以 GNU 并行方式传递参数。例如,我有三个 bash 脚本,我想使用 GNU 并行并行运行它们

“par1.sh”,“par2.sh”,“par3.sh”。我的脚本如下所示:

Filecount=$(grep -c "if" $1)

echo $Filecount

parallel -j0 sh ::: par$(seq 1 $Filecount).sh

mkdir $2
mv par$(seq 1 $Filecount).sh ./$2

我尝试了一切可能的方法来运行此代码,但它不起作用。因此,我的问题是如何为 GNU 并行提供变量。我也尝试过这个:

par{1..$Filecount}.sh

但它也不起作用,我也尝试过“seq”。

答案1

问题不在于并行,而在于您传递的“变量”。这par$(seq 1 $Filecount).sh将扩展为(假设Filecount=10):

$ echo par$(seq 1 $Filecount).sh
par1 2 3 4 5 6 7 8 9 10.sh

你希望它像大括号扩展一样工作:

$ echo par{1..10}.sh
par1.sh par2.sh par3.sh par4.sh par5.sh par6.sh par7.sh par8.sh par9.sh par10.sh

但是,变量不会在大括号扩展内扩展:

$ echo par{1..$Filecount}.sh
par{1..10}.sh

好消息是,这些实际上都不需要。您可以执行以下操作之一:

  1. 使用普通的 glob

    parallel -j0 sh ::: par*sh
    

    也许

    parallel -j0 sh ::: par[0-9]*.sh
    
  2. 预先构建变量

    targets=""; for ((num=1;num<=$Filecount;num++)); do targets="$targets par$num.sh"; done
    parallel -j0 sh ::: $targets
    

因此,使用第二种方法,您的脚本将变成(稍微修改以使其安全地使用任意文件名;与您的情况无关,但可能适合未来的访问者):

Filecount=$(grep -c "if" "$1")

echo "$Filecount"

targets=( "par1.sh" ); 
for ((num=2;num<=$Filecount;num++)); do 
    targets=("${targets[@]}" par"$num".sh); 
done
parallel -j0 sh ::: "${targets[@]}"

mkdir "$2"
mv "${targets[@]}" ./"$2"

答案2

mkdir $2
seq $Filecount | parallel -j0 sh par{}.sh';' mv par{}.sh ./$2

相关内容