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

Posted

技术标签:

【中文标题】在 BASH 中使用嵌套 for 循环运行 2x3x6 变量循环【英文标题】:Using nested for loop in BASH to run 2x3x6 variable loop 【发布时间】:2022-01-04 03:53:57 【问题描述】:

我想对我的数据运行一个命令,该命令在 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是代码中使用的实际图片的变量

$file1_LEFT 变量示例:/path/to/variable/file1_LEFT.nii.gz

$a 是一个命名变量(右/左)

$b$file 的命名变量,因为我不能使用文件路径/名称

为清楚起见,在$b:

ROI1 代表file1_LEFTfile1_RIGHT

ROI2 代表file2_LEFTfile2_RIGHT

ROI3 代表file3_LEFTfile3_RIGHT

所以循环中的命令将调用$file 变量,但因为我不能使用文件作为名称,所以我创建了$b 变量严格用于命名目的。但是,这将不起作用,因为如果不将 ROI 与所有文件混合,我将无法分离 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
.
.

【问题讨论】:

【参考方案1】:

另一个潜在的解决方案是将您的“投资回报率”加载到一个数组中并循环遍历它们,例如

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 ROI1..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 ROI1..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

【讨论】:

这与我所寻求的很接近,我在原始帖子中不清楚,并已更新以进一步解释 如果我为左右半边制作两个循环,则此方法有效【参考方案2】:

请您尝试以下方法:

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

【讨论】:

我认为我的问题不清楚并已更新。这接近我想要得到的,但我认为不适用于我的数据【参考方案3】:

只需遍历左右。以下代码:

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

【讨论】:

我无法将左右半球与左右 ROI 混合,如果不清楚,请见谅

以上是关于在 BASH 中使用嵌套 for 循环运行 2x3x6 变量循环的主要内容,如果未能解决你的问题,请参考以下文章

在 for 循环中嵌套 if

c语言中的循环的嵌套是怎么运行的

BASH:在 for 循环中使用 continue

如何将两个for循环嵌套使用,要求内层循环结束,外层也一起结束。

您如何在方案中运行等效的嵌套 for 循环

VB.NET 在 Parallel.for Synclock 内的嵌套循环中运行 sum 丢失信息