0

I had to recover a micro-sd card using photorec. I'm left with a dir that contains lots of other dirs which also include multiple file extensions. I would like to move each file to a new dir based on the file extension:

*.jpg moved to dir /SortedDir/jpg

*.gif moved to dir /SortedDir/gif

Also needing to take into account raw files with no extension or *.<'blank>

I have done this successfully in a batch on Windows:

@Echo OFF

Set "Folder=C:\MessyDir"
Set "DestDir=C:\SortedDir"

FOR /R "%Folder%" %%# in ("*") DO (
    If not exist "%DestDir%\%%~x#" (MKDIR "%DestDir%\%%~x#")
    Echo [+] Moving: "%%~nx#"
    Move "%%#" "%DestDir%\%%~x#\" 1>NUL
)

Pause&Exit

Looking for a linux script version.

Thanks!!

kisk
  • 101

2 Answers2

0

Assuming all the unsorted files are in messy_dir and your subdirectories are in sorted_dir, you could do something like this:

(cd sorted_dir; mkdir jpg gif)
find messy_dir -type f \( -iname '*.jpg' -exec mv {} ../sorted_dir/jpg/ \; -o \
                          -iname '*.gif' -exec mv {} ../sorted_dir/gif/ \; \)

This could be improved but it's a decent starting point.


If you want to have a script instead, try something like the following:

#!/bin/bash

# Check assumptions
[ "$#" -eq 2 ] || exit 1
[ -d "$1" ] || exit 1

find "$1" -type f -name '*?.?*' -exec sh -c '
    mkdir -p "$2/${1##*.}" && mv "$1" "$2/${1##*.}"
' find-sh {} "$2" \;
Wildcard
  • 36,499
-1

Using some of your parameters:

#!/bin/bash

# collect directory names
MessyDir="$1"
SortedDir="$2"

# test if user supplied two arguments
if [ -z $2 ]; then
    echo "Error: command missing output directory" 
    echo "Usage: $0 input_dir output_dir" 
    exit 1
fi

# read recursively through MessyDir for files 
find $MessyDir -type f | while read fname; do

    # form out_dir name from user supplied name and file extension
    out_dir="$SortedDir/${fname##*.}"

    # test if out_dir exists, if not, then create it
    if [ ! -d "$out_dir" ]; then
        mkdir -p "$out_dir"
    fi

    # move file to out_dir
    mv -v "$fname" "$SortedDir/${fname##*.}"

done

This is a bit more drawn out than necessary and requires Bash 4 or higher because of the variable expansion ${fname##*.} This avoids a call to basename and will work fine with photorec. Also, this script will work for all file types exported by photorec, not just jpg and gif.