【问题标题】:Using nested for loop in BASH to run 2x3x6 variable loop在 BASH 中使用嵌套 for 循环运行 2x3x6 变量循环
【发布时间】: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
.
.

【问题讨论】:

    标签: bash for-loop nested-loops


    【解决方案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 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
    

    【讨论】:

    • 这与我所寻求的很接近,我在原始帖子中不清楚,并已更新以进一步解释
    • 如果我为左右半边制作两个循环,则此方法有效
    【解决方案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 混合,如果不清楚,请见谅
    猜你喜欢
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多