------------------------------------------------------------------------ retain selective files in a directory ------------------------------------------------------------------------ This problem was posted by Lankeshwar Dey, DAA, TIFR. "Delete all files in a directory except few particular files." $ touch {1..3}.txt $ touch {a,b}.txt $ ls 1.txt 2.txt 3.txt a.txt b.txt Our goal is to only retain a.txt and b.txt whilst deleting all other files. The file "list" contains a list of files which we wish to preserve. This list should also include the name of the "list file". $ cat list #list of files you want to keep a.txt b.txt list #do not forget to include the listing file itself We will use the task "comm" which can find lines common to two -sorted- files. The two files are "ls -1" and the list of files we wish to keep. The list presented by "ls -1" is sorted. We need to sort our list. Thus $ comm -2 -3 <(ls -1) <(cat list | sort) 1.txt 2.txt 3.txt Now we are all set $ comm -2 -3 <(ls -1) <(cat list | sort) | sed 's/^/rm /' rm 1.txt rm 2.txt rm 3.txt Happy with the outcome? Then execute it! $ comm -2 -3 <(ls -1) <(cat list | sort) | sed 's/^/rm /' | sh -x You can save two strokes by combining the options for comm $ comm -23 <(ls -1) <(cat list | sort) | sed 's/^/rm /' | sh -x ------------------------------------------------------------------------ Approach 2: using xargs ------------------------------------------------------------------------ $ comm -2 -3 <(ls -1) <(cat list | sort) | xargs -n 1 -I {} rm {} ------------------------------------------------------------------------ Approach 3: most elegant (least keystrokes) ------------------------------------------------------------------------ $ echo $(comm -23 <(ls -1) <(cat list|sort)) 1.txt 2.txt 3.txt $ rm $(comm -3 <(ls -1) <(cat list|sort)) Weakness: This approach fails if the filenames do not follow classic Unix file name framework (which restricts filenames to alphabets, digits, underscore but not " " etc)