#!/bin/bash

if [ -z "$1" ] ; then
	echo "rmx [rm options] [--] <files> ..."
	echo
	echo 'Removes all files in current directory *excluding* files specified.'
	echo 'All the usual rm options (eg -i) can be passed on.'
	echo 'Specify the end of options using -- if your first file begins with a -'
	echo 
	echo 'Are you sure you want this untested piece of hackery?'
	echo 'If you are using bash/ksh/zsh you could just do:'
	echo '	rm !(*.c|*.h)'
	echo 'ksh allows this by default, for other shells set options:'
	echo 'bash: shopt -s extglob'
	echo ' zsh: setopt KSH_GLOB NO_BARE_GLOB_QUAL'
	echo 'tcsh and zsh: lets you negate some things with a ^ depending on options'
	echo
	exit
fi

# Iain Murray March 2005
# Absolutely no liability accepted. Be really careful. Test it to your
# satisfaction first.
#
# Inspired by a script by Ben Okopnik, 1/2001
# found on the web. But that script didn't support spaces in filenames, and
# didn't use the same globbing and options as rm.
#
# BUGS:
# rm accepts arguments anywhere on the command line. I insist they are all
# before the files.
# arguments are assumed to not contain spaces (but they don't so that's ok)
# Should cope with lots of files, but will be slow doing it.
# Filenames can contain line breaks too (!) that confuses this script.

args=""
for a in "$@" ; do
	if [ "${a:0:2}" = "--" ] ; then break ; fi
	if [ "${a:0:1}" = "-" ] ; then
		args="$args $a"
		shift
	else
		break
	fi
done

OLDIFS="$IFS"
IFS="
"

# all the pipeline stuff is because user might do rm -i
# and needs to be allowed to give input
exec 5<&0 # save user's standard in
(echo "$*"; echo "$*" ; ls -1 ) | sort | uniq -u | while read f ; do
	IFS="$OLDIFS"
	exec 6<&0 # save pipeline standard in
	exec 0<&5 # restore user's standard in
	rm $args -- "$f"
	exec 5<&0 # save user's standard in
	exec 0<&6 # restore pipeline standard in
done
