在 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_LEFT
和file1_RIGHT
ROI2 代表file2_LEFT
和file2_RIGHT
ROI3 代表file3_LEFT
和file3_RIGHT
所以循环中的命令将调用$file
变量,但因为我不能使用文件作为名称,所以我创建了$b
变量严格用于命名目的。但是,这将不起作用,因为如果不将 ROI 与所有文件混合,我将无法分离 ROI,例如,我无法获得组合 ROI1_file2
或 ROI1_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
它使用循环变量a
和b
生成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 变量循环的主要内容,如果未能解决你的问题,请参考以下文章