I have numerous files I am trying to move from a main directory in to separate directories which have multiple sub-directories inside.

Example file naming conventions 1SA_1BA_1W.out, 2SA_3BA_3W.out, 4SA_2BA_5W.out.... Is there a way given the number in from of each SA, BA, W or other items I have to move all at one time to a given location. The ranges of SA would be 1-10, BA 1-4 ect... Currently I am using a script command such as........

find . -type f -name '1A_1HNO3_W.out' | xargs -I {} cp '{}' /location/A_HNO3
find . -type f -name '2SA_BA_W.out' | xargs -I {} cp '{}' /location/SA_BA_W 
find . -type f -name '3SA_BA_W.out' | xargs -I {} cp '{}' /location/SA_BA_W 
find . -type f -name '4SA_BA_W.out' | xargs -I {} cp '{}' /location/SA_BA_W 
find . -type f -name '1SA_DEA_W.out' | xargs -I {} cp '{}' /location/SA_DEA_W 
find . -type f -name '2SA_DEA_W.out' | xargs -I {} cp '{}' /location/SA_DEA_W 
find . -type f -name '3SA_DEA_W.out' | xargs -I {} cp '{}' /location/SA_DEA_W 
find . -type f -name '4SA_DEA_*W.out' | xargs -I {} cp '{}' /location/SA_DEA_W

have over 1700 files with various identification abbreviations, such as SA BA A HNO3 W MA EAM TMA DMA DEA ect... I need to be able to get pull these files and transfer them into an easy database structure. The "location" would be the name of the main parent directory and folders like SA_DEA_W are sub directories inside the parent directory.

3 Answers 3

mv *SA_BA_W.out  /location/SA_BA_W;

mv *SA_DEA_W.out /location/SA_DEA_W

and so on.


You can create directories one time using below command:

Create sub-directories

ls *.out | sed -Ee 's/[0-9]*([A-Za-z]+)_([0-9]*[A-Za-z]+[0-9]*)_W.out$/\1_\2_W/g' | awk ' { system("mkdir -p /location/" $0) }'


find . -regextype awk -regex './([0-9]*[A-Za-z])+_([0-9]*[A-Za-z]+[0-9]*)_W.out' | sed -Ee 's/[0-9]*([A-Za-z]+)_([0-9]*[A-Za-z]+[0-9]*)_W.out$/\1_\2_W/g' | awk '{ system("mkdir -p /location/" $0) }'


find . -regextype awk -regex './([0-9]*[A-Za-z])+_([0-9]*[A-Za-z]+[0-9]*)_W.out' | sed -Ee 's/[0-9]*([A-Za-z]+)_([0-9]*[A-Za-z]+[0-9]*)_W.out$/\1_\2_W/g' | xargs -I {} mkdir -p /location/{}

YOU CAN DO BOTH operations using below for loop

To Create sub directories and Move the files to the respective directories :

for i in $(ls *.out)
DIR_NAME=$(echo $i | sed -Ee 's/[0-9]*([A-Za-z]+)_([0-9]*[A-Za-z]+[0-9]*)_W.out$/\1_\2_W/g')
test -d /location/$DIR_NAME || mkdir /location/$DIR_NAME
mv $i $DIR_NAME

You could try

find . -iname "*.out" -exec sh -c '
     [ ! -d $f ] && mkdir -p $d;
     mv $1 $d'  sh {} \;

Provided you have no spaces in your file paths


Find all of your .out files, and for each one -exec .... \;

find . -iname "*.out" -exec sh -c '...script...` sh {} \; 

The construct

sh -c `...script......` sh {}

Takes each file name as {} and passes it back into the script as $1 where we

Remove the directory path to the last / and store is as f


Remove the .out suffix


Calculate the directory you want and store it as d


Create the directory if it doesn't exist, together with any parents -p

         [ ! -d $d ] && mkdir -p $d;

Do the move

         mv $1 $d'  sh {} \;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.