在 BASH 到 运行 2x3x6 变量循环中使用嵌套 for 循环

Using nested for loop in BASH to run 2x3x6 variable loop

我想 运行 对我的数据执行一个命令,该命令在 2 个半球内注册 3 个感兴趣区域 (ROI) 并适当地命名每个输出。我无法弄清楚如何在嵌套循环中保留一行命令,而不是将循环分解为几个特定的​​ ROI 循环。

一般来说,是这样的:

for a in Right_hemi Left_hemi; do
    for b in ROI1 ROI2 ROI3; do
        for file in ${file1_LEFT} ${file2_LEFT} ${file3_LEFT} ${file1_RIGHT} ${file2_RIGHT} ${file3_RIGHT}; do

            antsApplyTransforms -d 3 -i $file  ${dir_out}/warped_atlas/${a}_${b}_${subject}.nii.gz 

            echo "${a}_${b}_${subject}.nii.gz"

        done
    done
done

$file是代码中使用的实际图片的变量

$a是命名变量(right/left)

$b$file 的命名变量,因为我不能使用文件 path/name

为清楚起见,在 $b 中:

所以循环中的命令将调用 $file 变量,但是因为我不能使用文件作为名称,所以我严格地创建了 $b 变量用于命名目的。但是,这将不起作用,因为如果不将 ROI 与所有文件混合,我将无法分离它们,例如,我无法将输出组合 ROI1_file2ROI1_file3。每个 $b 名称必须匹配适当的 $file 变量,因此输出应该是:

Left_hemi_ROI1*.gz  # where ROI1 represents file1_LEFT
Right_hemi_ROI1*.gz # where ROI1 represents file1_RIGHT
Left_hemi_ROI2*.gz  # where ROI2 represents file2_LEFT
Right_hemi_ROI2*.gz # where ROI2 represents file2_RIGHT
.
.

请您尝试以下操作:

for a in Right_hemi Left_hemi; do
    a2=${a%_*}                          # remove underscore and following characters
    for b in ROI1 ROI2 ROI3; do
        varname="${b}_${a2^^}"          # concatenate $b, "_", and uppercased "$a2"
        ROI=${!varname}                 # indirect variable reference
            antsApplyTransforms -d 3 -i "$ROI" -r "${dir_out}/FA_${subject}".nii.gz -o "${dir_out}/warped_atlas/${a}_${b}_${subject}.nii.gz"
            echo "${ROI} warp completed"
    done
done

它使用循环变量 ab 生成 varname 例如 ROI1_LEFT 然后通过 ${varname} 访问 $ROI1_LEFT

另一种可能的解决方案是将“ROI”加载到数组中并循环遍历它们,例如

c=('${ROI1_LEFT}' '${ROI2_LEFT}' '${ROI3_LEFT}' '${ROI1_RIGHT}' '${ROI2_RIGHT}' '${ROI3_RIGHT}')

i=0
for f in Left_hemi Right_hemi
do
    for g in ROI{1..3}
    do
        echo "${f}_${g}_${c[i]}_subject.gz"
        i=$(( i + 1 ))
    done
done
Left_hemi_ROI1_${ROI1_LEFT}_subject.gz
Left_hemi_ROI2_${ROI2_LEFT}_subject.gz
Left_hemi_ROI3_${ROI3_LEFT}_subject.gz
Right_hemi_ROI1_${ROI1_RIGHT}_subject.gz
Right_hemi_ROI2_${ROI2_RIGHT}_subject.gz
Right_hemi_ROI3_${ROI3_RIGHT}_subject.gz

所以,关于如何将其应用于实际数据,我的猜测是:

c=(${ROI1_LEFT} ${ROI2_LEFT} ${ROI3_LEFT} ${ROI1_RIGHT} ${ROI2_RIGHT} ${ROI3_RIGHT})

for subject in subjects
do
    i=0
    for f in Left_hemi Right_hemi
    do
        for g in ROI{1..3}
        do
            antsApplyTransforms -d 3 -i ${c[i]} -r ${dir_out}/FA_${subject}.nii.gz -o ${dir_out}/warped_atlas/"${f}_${g}_${c[i]}_${subject}.nii.gz" 
        i=$(( i + 1 ))
        done
    done
done

只需左右迭代即可。以下代码:

for a in Right_hemi Left_hemi; do
    for b in ROI1 ROI2 ROI3; do
        for direction in LEFT RIGHT; do
             echo "${a}_${b}_${${b}_${direction}}_*.gz"
        done
    done
done | head -n 3

输出:

Right_hemi_ROI1_${ROI1_LEFT}_*.gz
Right_hemi_ROI1_${ROI1_RIGHT}_*.gz
Right_hemi_ROI2_${ROI2_LEFT}_*.gz