#!/bin/bash

## Yr basic friendly error output.
help_output() {
    echo
    echo "$0 is a bash script which moves files by using a regular "
    echo "expression on their filenames."
    echo "Usage: "
    echo "  $0 [OPTION] regexp [DIRECTORY]"
    echo "Examples: "
    echo "  $0 -f s/foo/bar/ ."
    echo "  $0 s/^rm$/blah_rm/ /bin"
    echo "Command line options include:"
    echo "  -f, Use mv -f to force overwrites (dangerous)."
    echo "  -q, Quiet, do work with as little output as possible."
    echo "  -a, Use regexp on dotfiles too, as in 'ls -A'."
    echo "  -d, Move directories as well as files."
    echo
}

## Print the move that is taking place.
show_move() {
    if ! [ $quiet ]; then
        echo "$from -> $to"
    fi
}

## Program flow begins here: int main etc
## Set up options.
while getopts "faqd" Opt; do
    case $Opt in
        f ) force='true';;
        a ) ls_all='true';;
        q ) quiet='true';;
        d ) movedirs='true';;
        ? ) help_output; exit;
    esac
done

## This theoretically shifts the arguments so that regexp and directory
## are in the correct places to be useful. AMAZINGLY OBTUSE ISNT IT??
shift $(($OPTIND - 1))

## Change directory to where we will be working.
wd=`pwd`
cd $2
if ! [ $? -eq 0 ]; then
    echo "  ERROR: could not cd to that directory."
    exit
fi

## We will be moving files FROM their original names TO some new names.
if [ $ls_all ]; then
    fromlisting=`ls -A1`
else
    fromlisting=`ls -1`
fi
for from in $fromlisting; do
    ## We don't really want to see the error, we just want it to go away.
    to=`echo $from | sed "$1" 2> /dev/null`
    if ! [ $? -eq 0 ]; then
        echo "  ERROR: sed failed, check your regular expression for validity. "
        help_output
        exit
    fi
    if [ "$from" != "$to" ]; then
        ## mv is a SHOTGUN. If you don't watch out you might shoot yourself
        ## in the FOOT.
        if [ $force ]; then
            if ! [ $movedirs ]; then
                if ! [ -d $from ]; then
                    ## Wow, bash flow control sure is bogus. Look at all
                    ## of this nesting!
                    show_move
                    mv -f "$from" "$to"
                fi
            else
                show_move
                mv -f "$from" "$to"
            fi
        else
            if ! [ $movedirs ]; then
                if ! [ -d "$from" ]; then
                    show_move
                    mv -i "$from" "$to"
                fi
            else
                show_move
                mv -f "$from" "$to"
            fi
        fi
    fi
done

## cd back to where we started.
cd $wd
