#!/bin/bash if [ -z "$1" ] ; then echo "rmx [rm options] [--] ..." 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