rmfiles


#!/bin/sh 

# AUTHOR:
#   Greg Keraunen <gk@proliberty.com>
#   4/11/2002

# PURPOSE: 
#   Recursively removes files below the specified directory, or current directory by default
#  Example: files are created by netatalk: '.AppleDouble' '.Icon ' 

# SETUP:
# 	sets of pre-defined shell patterns must reside in the "patterns" directory, below this script
#	each pattern-file name must have format:
#		"<pattern-set-name>.rmfiles"
#		such as, "rmfiles_directory/patterns/afp.rmfiles", for example
# 	create a pattern file to use with shell patterns; don't wrap with quotes; one pattern per line; no comments
#	pass the pattern file to this command with: rmfiles -f pattern_file

#	If you specify a set of patterns with -p, this takes precedence over -f

# USAGE:
#   rmfiles.sh [OPTIONS] [directory] 

# QUESTIONS/ TODO:

# NOTES:
# 	if you see shell error message: .../.AppleDouble: Permission denied  
#	this is due to recursively trying to execute 'find' command on directories that may not be executible or may have been deleted already
#==============================================================================
#### DEFAULT SETTINGS:
USAGE="Usage: rmfiles.sh [OPTIONS] [directory]"
INPUT_FILE="/dev/stdin"
DIRECTORY=`pwd`
#### END OF DEFAULT SETTINGS
USER_DIR=`pwd`

#the pattern file directory
PATTERN_DIR="patterns"
PATTERN_EXT="rmfiles"

help()
{
        cat << eof
$USAGE
Options:
	-v             - verbose; print which files were deleted
	-f input_file  - specify an input file name of filename patterns to delete
	-p pattern_set - specify a pre-defined set of filename patterns to delete
	-h             - print this help text
eof
}

# syntax of getopts is:
#	: indicates option expects argument string after; E.g., -o output_file
#	without :, option doesn't expect anything else; E.g., -h
while getopts ":vhf:p:" Option
do
    # ;; required after each case 
    case $Option in
    h     ) help; exit 0;;
    f     ) INPUT_FILE=$OPTARG;;
    p     ) # the installed directory:
            # get directory of this script; careful of symbolic links
            if [ -L "$0" ]
            then 
	            cd -P "$(dirname $0)"  
	            cd -P "$(dirname $(readlink $0 ))" 
            else
	            cd -P "$(dirname $0)"  
            fi
			INPUT_FILE=`pwd`"/$PATTERN_DIR/$OPTARG.$PATTERN_EXT"
    		;;
    v     ) VERBOSE=true;;
    *     ) echo "Unimplemented option chosen: $1"; exit 1;;   
    esac
done

# this decrements the argument pointer so it points to next argument after the options.
shift $(($OPTIND - 1))

if [ ! -z "$1" ]  # If directory is specified
then
    if [[ $(basename "$1") = "$1" ]] 
    then
    	# if $1 is a relative path
		DIRECTORY="$USER_DIR""/$1"
    else
    	# if $1 is an absolute path
	    DIRECTORY="$1"
    fi
fi

# if DIRECTORY is a symbolic link, we need to dereference it
if [ -L "$DIRECTORY" ]
then  
	DIRECTORY=$(readlink "$DIRECTORY" ) 
fi

if [ ! -e "$INPUT_FILE" ]  # If input file doesn't exist
then
	echo "error: input file not found: \"$INPUT_FILE\""; exit 1;
fi

# for debugging:
#echo "current directory: `pwd`"
#echo "$INPUT_FILE"; 
#echo "1=$1; 2=$2; 3=$3; 4=$4"
#echo "$DIRECTORY"; exit;

# this deletes any file that matches a shell PATTERN from INPUT_FILE:
cat "$INPUT_FILE" | while read PATTERN
do 
find "$DIRECTORY" -name "$PATTERN" 2>/dev/null | while read FILE
    do
    	rm -rf "$FILE" 2>/dev/null 
    	if [[ $? && $VERBOSE ]]
        then 
        	echo "deleted file: $FILE" 
        fi
    done
done