Использование вложенного цикла for в BASH для запуска цикла переменных 2x3x6

#bash #for-loop #nested-loops

Вопрос:

Я хотел бы запустить команду на своих данных, которая регистрирует 3 области интереса (ROI) в пределах 2 полушарий и соответствующим образом называет каждый вывод. У меня возникли проблемы с пониманием того, как сохранить одну строку команды во вложенном цикле, вместо того, чтобы разбивать цикл на несколько конкретных циклов рентабельности инвестиций.

В общем, что-то вроде этого:

 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, не смешивая их со всеми файлами, например, у меня не может быть выходного объединения 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 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  

Комментарии:

1. Это близко к тому, что я ищу, я был неясен в своем первоначальном посте и обновил, чтобы подробнее объяснить

2. Это работает, если я сделаю две петли по одной для правого и левого подола

Ответ №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  

Он генерирует varname , например, ROI1_LEFT с помощью переменных цикла a , а b затем получает доступ $ROI1_LEFT через ${varname} .

Комментарии:

1. Я думаю, что я был неясен в своем вопросе и обновил его. Это близко к тому, что я пытаюсь получить, но я не думаю, что это работает для моих данных

Ответ №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  

Комментарии:

1. Я не могу смешивать левый и правый hemi с левым и правым ROIs, извините, если это было неясно