#!/bin/bash # Todo: implement --rename PATH=$PATH:$(dirname "$0") # Check for required programs before starting requiredPrograms=( "cmp" "identify" "basename" "dirname" "rm" "cp" "mv") requiredOk=1 for prg in "${requiredPrograms[@]}"; do path=$(which $prg) if [[ "" == "$path" ]]; then requiredOk=0 echo "ERROR: Required program '$prg' not found" >&2 fi done if [[ $requiredOk -eq 0 ]]; then echo " Please provide those programs in order to use this script" >&2 exit 2 fi # General help that is shown whenever the script cannot be run because the user # did not provide sufficient parameters function showHelp { cmd=$(basename "$0") echo "" echo " -----===== $cmd =====-----" echo "" echo "Copies pictures in a given folder into another one ordering them in" echo "subfolders named after the image-resolution (e.g. '1280x1024')" echo "" echo "Obligatory parameters:" echo " --indir= The directory from which to take the images" echo " (It searches in all sub-folders for images)" echo " --outdir= The directory in which to place the ordered Images" echo "" echo "Optional parameters:" echo " --keepSubdirs Creates the original subdir from where the image was" echo " copies as a subdirectory of the outdir" echo " --move Move the images instead of copying them" echo " --remDouble (only with --move) Delete source file if target is the" echo " same" echo " --verbose Output information on every file that is copied/moved" echo " --rename Renames the copied files so that they only contain" echo " the characters a-z,0-9,- and _" echo "" echo "Example: " echo " \"$cmd --indir=Pictures/Wallpapers --outdir=Pictures/OrderedWallpapers\"" echo "" echo "Exit-Codes:" echo " 0 - Everything is fine" echo " 1 - Wrong parameters" echo " 2 - A target directory could not be created. Script aborted in the middle of work." echo " 3 - A file could not be copied. Script aborted in the middle of work." echo " 4 - Unknown parameter given" echo " 23 - I am watching you." echo " 42 - Please state the question." echo " 99 - The requested feature is not (yet) implemented" echo "" } # Used to output certain information only in verbose-mode function echoIfVerbose { if [[ $verbose -eq 1 ]]; then echo $@ fi } # initializing variables exitStatus=0 indir="" outdir="" keepSubdirs=0 verbose=0 rename=0 move=0 removeDouble=0 # Analyze given parameters for param in "$@"; do knownParam=0 if [[ "${param:0:8}" == "--indir=" ]]; then knownParam=1 indir="${param:8}" # All directories should end with an "/" to prevent problems with the # path later on if [[ "/" != ${indir: -1} ]]; then indir="$indir/" fi if [[ ! -d "$indir" ]]; then echo "ERROR: No directory ($indir)" >&2 echo " Please provide an existing directory as indir parameter" >&2 indir="" exitStatus=1 fi fi if [[ "${param:0:9}" == "--outdir=" ]]; then knownParam=1 outdir="${param:9}" # All directories should end with an "/" to prevent problems with the # path later on if [[ "/" != ${outdir: -1} ]]; then outdir="$outdir/" fi if [[ ! -d "$outdir" ]]; then echo "ERROR: No directory ($outdir)" >&2 echo " Please provide an existing directory as indir parameter" >&2 outdir="" exitStatus=1 fi fi if [[ "${param:0:13}" == "--keepSubdirs" ]]; then knownParam=1 keepSubdirs=1 fi if [[ "${param:0:6}" == "--move" ]]; then knownParam=1 move=1 fi if [[ "${param:0:9}" == "--verbose" ]]; then knownParam=1 verbose=1 fi if [[ "${param:0:11}" == "--remDouble" ]]; then knownParam=1 removeDouble=1 fi if [[ "${param:0:8}" == "--rename" ]]; then knownParam=1 rename=1 echo "ERROR: --rename is currently not implemented!" >&2 exitStatus=99 fi # Check for unknown parameters # Has to be at the end of this loop if [[ $knownParam -eq 0 ]]; then echo "ERROR: Unknown Parameter '$param'" >&2 exitStatus=4 fi done if [[ "$indir" == "" || "$outdir" == "" ]]; then echo "ERROR: Obligatory Parameters not given" >&2 echo " Please provide existing directories as indir and outdir parameters" >&2 exitStatus=1 fi if [[ $exitStatus -ne 0 ]]; then ## Code for debugging parameters #echo "Parameters received:" #x=0 #while [[ "$1" != "" ]]; do # let "x = $x + 1" # echo "$x: $1" # shift #done showHelp exit $exitStatus fi # $IFS must be set to newline so a space is not interpreted as separator for # the files returned by the find-command IFS=$'\n' # Find all files (including 'hidden' .-files) files=$(find "$indir" -type f) for filePath in $files; do type=$(file -b -i "$filePath" | cut -c 1-5) # Check if the file is an image if [[ "image" != "$type" ]]; then echoIfVerbose "Not an image: '$filePath'" continue fi # Check if the picture is ok error=$(identify -regard-warnings "$filePath" 2>&1 >/dev/null) status=$? if [ $status -ne 0 ]; then echo "The image is corrupt or known format: $filePath" >&2 continue fi # Give Picture Size as "WIDTHxHEIGHT" pictureSize=$(identify -format "%wx%h" "$filePath") # Get only the filename - without path basename=$(basename "$filePath") from="$filePath" to="$outdir/$pictureSize/$basename" # Keep sub directories if this is what the user wishes if [[ $keepSubdirs -eq 1 ]]; then subPath=${filePath/#"$indir"/""} to="$outdir/$pictureSize/$subPath" fi # Check if file already exists x=0 while [[ -f "$to" ]]; do cmp -s "$from" "$to" status=$? # Check if existing file ist the same else rename new file if [[ $status -eq 0 ]]; then # files are the same echoIfVerbose "Picture '$to' already exists and is the same" to="" if [[ $removeDouble -eq 1 ]]; then echoIfVerbose "Deleting source file '$from'" rm "$from" fi break fi let "x = $x + 1" to="$x-$to" done # If $to is empty, continues with the next image if [[ "$to" == "" ]]; then continue fi # Create directories if not already there toDir=$(dirname "$to") if [[ ! -d "$toDir" ]]; then error=$(mkdir -p "$toDir" 2>&1 >/dev/null) status=$? if [ $status -ne 0 ]; then echo "ERROR: Could not create directory: '$toDir'" >&2 echo " Please make sure you have sufficient permissions and try again" >&2 exit 2 fi fi if [[ $move -eq 1 ]]; then action="Moving" mv "$from" "$to" else action="Copying" cp "$from" "$to" fi echoIfVerbose "$action: '$from' --> '$to'" status=$? if [[ $status -ne 0 ]]; then echo "ERROR: Could not copy file: '$from' to '$to'" >&2 echo " Please make sure you have sufficient permissions and try again" >&2 exit 3 fi done