0

I have 100+ subfolders (P_XXX), each containing three sets of files (run1, run2 and run3):

/Analysis   
  /P_076
      /run1
      /run2
      /run3
      swu_run1_P_076_vol_001.nii
      swu_run1_P_076_vol_002.nii
      swu_run2_P_076_vol_001.nii
      swu_run2_P_076_vol_002.nii
      swu_run3_P_076_vol_001.nii
      swu_run3_P_076_vol_002.nii   
   /P_102
      /run1
      /run2
      /run3
      swu_run1_P_102_vol_001.nii
      swu_run1_P_102_vol_002.nii
      swu_run2_P_102_vol_001.nii
      swu_run2_P_102_vol_002.nii
      swu_run3_P_102_vol_001.nii
      swu_run3_P_102_vol_002.nii

I would like to move the three sets of files to its own subfolders (run1, run2 and run3) within the existing subfolder:

/Analysis
  /P_076
     /run1 
        swu_run1_P_076_vol_001.nii
        swu_run1_P_076_vol_002.nii
     /run2
        swu_run2_P_076_vol_001.nii
        swu_run2_P_076_vol_002.nii
     /run3
        swu_run3_P_076_vol_001.nii
        swu_run3_P_076_vol_002.nii
  /P_102
     /run1
        swu_run1_P_102_vol_001.nii
        swu_run1_P_102_vol_002.nii
      /run2 
        swu_run2_P_102_vol_001.nii
        swu_run2_P_102_vol_002.nii
      /run3
        swu_run3_P_102_vol_001.nii
        swu_run3_P_102_vol_002.nii

The below code does the trick when I run the script within the subfolder (P_XXX):

for f in swu_run?_*.nii; do
       num=${f:7:1}
       mv "$f" run"$num"/
    
done'

But I am struggling to find the appropriate for loop to make it work from the parent directory (Analysis), rather than manually running it within each subfolder. I tried the following:

find . -type f -name '*.nii' -exec bash -c '
for f in swu_run?_*.nii; do
     num=${f:7:1}
     mv "$f" run"$num"/
 
done' bash {} +

This returns the error message cannot stat 'swu_run?_*.nii': No such file or directory.

How do I run the code at the level of the Analysis folder, so that each P_XXX subfolder is reorganised in three further subfolders (run1, run2 and run3) with their matching files in one go?

1
  • The bash -c script in your find command already gets a number of pathnames to files with names ending in .nii. You should not need to expand any filename globbing pattern in that script. Commented Jun 16, 2020 at 14:51

1 Answer 1

1

You could use two loops with bash:

cd /path/to/Analysis
shopt -s nullglob
for i in {1..3}; do
  for f in */swu_run${i}_*.nii; do
     mv "$f" "${f%/*}/run${i}/"
  done
done

The enabled nullglob shell option makes sure that the inner loop is not entered if */swu_run${i}_*.nii doesn't match any files (already moved or missing).

The parameter expansion ${f%/*} removes the shortest suffix pattern /* leaving the path of the parent directory.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.