Search code examples
linuxloopswildcardmove

Moving multiple files to multiple directories based on filename pattern, while excluding some


As a Linux noob (that wants to learn!), I have been browsing and searching but unfortunately not been able to come up with the right solution for my problem. I've got a directory containing several files (a lot) that I'd would like to move to different directories (to be made also). To be more specific:

my directory is: /data/myowndir/ and the files each have names such as

  • CV02_T1_[random characters].REC
  • PM03_T2_[random characters].PAR

I would like to move each file to a subdirectory inside this directory by their respective first 7 characters (of the filename), such that:

  • CV02_T1_*.REC ---> /data/myowndir/CV02_T1
  • CV02_T1_*.PAR ---> /data/myowndir/CV02_T1 (same directory as previous)
  • PM03_T1_*.REC ---> /data/myowndir/PM03_T1
  • PV05_T2_*.PAR ---> /data/myowndir/PV05_T2
  • etc.

So I want to move multiple files and create these multiple directories.

However, there are two contraints.

  1. The directory also contains files with the extension .nii , which I don't want to move.
  2. Second, some files have filenames containing the string sT13, which I would like to move to a separate directory, such that:

PM03_T2_[random characters]sT13[random characters].PAR ---> /data/myowndir/PM03_struc

(so only the first 5 characters of the filename and the additional string [struc] added to the new directoryname)

Anyone know how to do this? Should I write a script or can I do this from the command terminal? I've been reading other answers to similar questions and man pages for mv, mmv, find, while, for, rsync; but I don't know how to put it together.


EDIT: If my question is too specific as implied, then let me rephraze it first to make it more clear and drop the contraints:

How do I move multiple files from a directory into multiple subdirectories, based on the first part of their filenames?


Solution

  • I'm assuming that there are more that two 7-letter sequences at the beginning of your filenames (because otherwise you could just mv commands with bash extension). On bash, fist move the 'special' files with the letter sequence in the middle to the new directory:

    cd  /data/myowndir/
    for filename in *sT13*.*; do
       if [ "${filename: -4}" != ".nii" ]; then
          dir_name=${filename:0:5};
          mkdir -p ${dir_name}struc
          mv -i $filename ${dir_name}struc/${filename}
       fi
    done
    

    then move all the other files to their respective new folders:

    for filename in *.*; do
       if [ "${filename: -4}" != ".nii" ]; then
          dir_name=${filename:0:7};
          mkdir -p $dir_name
          mv -i $filename $dir_name/${filename}
       fi
    done
    

    the -p option for the mkdir command assures that you don't get errors if the directory already exists. ${string:0:7} selects the first 7 letters of a string