Home > database >  Bash Script to move files based on their Prefix
Bash Script to move files based on their Prefix

Time:01-26

I take pictures for my job on three different cameras. I am looking to automate the process of organising these to folders based on the first 3 letters and then the filetype.

Unfortunately my bash script syntax knowledge is non existent and so I can't figure out more than creating the directories..

An eg of the incoming files:

HAM1234.JPG
HAM1234.RAW
HDR1234.JPG
HDR1234.RAW
STL1234.JPG
STL1234.RAW

These would go into 3 folders

HAM - REF/{RAW,JPG}
HDR - HDRI/{RAW,JPG}
STL - STILLS/{RAW,JPG}

With the filetypes being aligned.

Any help would be much appreciated!

Jason

CodePudding user response:

With your shown examples:

#!/bin/bash

mkdir -p {HAM\ -\ REF,HDR\ -\ HDRI,STL\ -\ STILLS}/{RAW,JPG}

shopt -s failglob

mv HAM*.JPG "HAM - REF/JPG"
mv HAM*.RAW "HAM - REF/RAW"

mv HDR*.JPG "HDR - HDRI/JPG"
mv HDR*.RAW "HDR - HDRI/RAW"

mv STL*.JPG "STL - STILLS/JPG"
mv STL*.RAW "STL - STILLS/RAW"

From man bash:

failglob: If set, patterns which fail to match filenames during pathname expansion result in an expansion error.

CodePudding user response:

Please refer a very basic bash script based on your requirements and information you provided:

#!/bin/bash

for files in *
do
    if [ -f "$files" ]; then
        fileprefix=${files%%[0-9]*.*}
        case $fileprefix in
            HAM)
                if [ ! -d REF ]; then
                    mkdir REF;
                fi
                mv "$fileprefix"*.* REF
            ;;
        
            HDR)
                if [ ! -d HDRI ]; then
                    mkdir HDRI;
                fi
                mv "$fileprefix"*.* HDRI
            ;;
        
            STL)
                if [ ! -d STILLS ]; then
                    mkdir STILLS;
                fi
                mv "$fileprefix"*.* STILLS
            ;;
        esac
    fi
done

The first logic for files in * assumes the script itself and all the image files resides in the same directory i.e. PWD.

if [ -f "$files" ]; then
Only run the logic if the matching item in the iteration is a file

fileprefix=${files%%[0-9]*.*}
Extract the letters (first 3) and store it in variable fileprefix

After that a simple switch-case follows.

You can modify the script as per your needs.

Hope this answers your question.

CodePudding user response:

Thanks Gaurav for the script. Editing it slightly I came out with this that seems to work. I wanted to be able to run it on a batch of folders at once for I added and extra loop and I ended up tweaking the folder structure. 2 questions, 1)Am I losing anything by using the mkdir -p command and removing the if statement? 2)What is the syntax behind ${files%%[0-9].} I just can't see how that pulls the first three chars? :D

#!/bin/bash

for f in "$@"; do
    cd "$f"
        for files in *
        do
            if [ -f "$files" ]; then
            fileprefix=${files%%[0-9]*.*}
            echo $fileprefix
            case $fileprefix in
                DSC)
                    mkdir -p "SetRef"
                    mv "$fileprefix"*.* SetRef
                ;;
    
                HDR)
                    mkdir -p "HDRI/JPG" "HDRI/ARW";
                    mv "$fileprefix"*.JPG HDRI/JPG
                    mv "$fileprefix"*.ARW HDRI/ARW
                ;;
     
                HAM)
                    mkdir -p "STILLS/JPG" "STILLS/ARW";
                    mv "$fileprefix"*.JPG STILLS/JPG
                    mv "$fileprefix"*.ARW STILLS/ARW
                ;;  
            esac
        fi
    done
done
  • Related